using System.Text; using NodePipeline.Engine.CodeGeneration.Abstractions; namespace NodePipeline.Engine.DependencyInjection.CodeGeneration; internal static class NodeFactoryGenerator { public static string Generate(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine("using Microsoft.Extensions.DependencyInjection;"); sb.AppendLine("using NodePipeline.Abstractions;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces.Nodes;"); sb.AppendLine("using NodePipeline.Configuration.Abstractions.Models.Execute;"); sb.AppendLine("using NodePipeline.Engine.Abstractions;"); sb.AppendLine("using NodePipeline.Engine.Abstractions.Validation;"); sb.AppendLine(); sb.AppendLine("// ReSharper disable CheckNamespace"); sb.AppendLine("// ReSharper disable NotAccessedField.Local"); sb.AppendLine("#nullable enable"); sb.AppendLine(); sb.AppendLine("namespace NodePipeline.Engine.Generated;"); sb.AppendLine(); sb.AppendLine("public class DiNodeFactory : INodeFactory"); sb.AppendLine("{"); sb.AppendLine(" private readonly INodeFactory _nodeFactory;"); sb.AppendLine(" private readonly IServiceProvider _serviceProvider;"); sb.AppendLine(); sb.AppendLine( " public IPipelineLocalizationProvider PipelineLocalizationProvider { get; set; } = new PipelineLocalizationProvider();"); sb.AppendLine(" public Dictionary> NodeFactories { get; set; } = [];"); sb.AppendLine(); sb.AppendLine( " public DiNodeFactory(IServiceProvider serviceProvider, INodeFactory inner, IPipelineLocalizationProvider? validationLocalizationProvider = null)"); sb.AppendLine(" {"); sb.AppendLine(" _serviceProvider = serviceProvider;"); sb.AppendLine(" _nodeFactory = inner;"); sb.AppendLine(" if (validationLocalizationProvider != null)"); sb.AppendLine(" {"); sb.AppendLine(" PipelineLocalizationProvider = validationLocalizationProvider;"); sb.AppendLine(" _nodeFactory.PipelineLocalizationProvider = PipelineLocalizationProvider;"); sb.AppendLine(" }"); sb.AppendLine(" InitializeNodeFactories();"); sb.AppendLine(" }"); sb.AppendLine(); sb.AppendLine(BuildInitializeNodeFactoriesMethod(model)); sb.AppendLine(); sb.AppendLine(BuildCreateNodeMethod()); sb.AppendLine(); sb.AppendLine(BuildGetParameterCodesMethod()); sb.AppendLine(); sb.AppendLine(BuildGetAllPortsMethod()); sb.AppendLine(); sb.AppendLine(BuildGetNodeInputPortsMethod()); sb.AppendLine(); sb.AppendLine(BuildReadParameterValueMethod()); sb.AppendLine(); sb.AppendLine(BuildGetParameterDefaultValueMethod()); sb.AppendLine(); sb.AppendLine(BuildSetNodeParametersValuesMethod()); sb.AppendLine(); sb.AppendLine(BuildConnectPortsMethod()); sb.AppendLine("}"); sb.AppendLine("#nullable restore"); return sb.ToString(); } private static string BuildInitializeNodeFactoriesMethod(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine(" private void InitializeNodeFactories()"); sb.AppendLine(" {"); foreach (var n in model.Nodes) { if (n.HasParameterlessConstructor) continue; sb.AppendLine(" _nodeFactory.NodeFactories.Add("); sb.AppendLine($" {NodeGeneratorHelper.GetNodeName(n)},"); sb.AppendLine($" () => _serviceProvider.GetRequiredService<{n.TypeNameFull}>());"); } sb.AppendLine(" }"); return sb.ToString(); } private static string BuildCreateNodeMethod() { var sb = new StringBuilder(); sb.AppendLine(" public INode CreateNode(string pipelineId, NodeConfig config)"); sb.AppendLine(" {"); sb.AppendLine(" return _nodeFactory.CreateNode(pipelineId, config);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildGetParameterCodesMethod() { var sb = new StringBuilder(); sb.AppendLine(" public IEnumerable GetParameterCodes(string nodeType)"); sb.AppendLine(" {"); sb.AppendLine(" return _nodeFactory.GetParameterCodes(nodeType);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildGetAllPortsMethod() { var sb = new StringBuilder(); sb.AppendLine( " public Dictionary GetAllPorts(string pipelineId, HashSet nodeTypes, Dictionary> nodeList)"); sb.AppendLine(" {"); sb.AppendLine(" return _nodeFactory.GetAllPorts(pipelineId, nodeTypes, nodeList);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildGetNodeInputPortsMethod() { var sb = new StringBuilder(); sb.AppendLine( " public IEnumerable GetNodeInputPorts(string pipelineId, string nodeType, string nodeId)"); sb.AppendLine(" {"); sb.AppendLine(" return _nodeFactory.GetNodeInputPorts(pipelineId, nodeType, nodeId);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildReadParameterValueMethod() { var sb = new StringBuilder(); sb.AppendLine( " public object? ReadParameterValue(string pipelineId, string nodeId, string nodeType, string parameterName, string valueString)"); sb.AppendLine(" {"); sb.AppendLine( " return _nodeFactory.ReadParameterValue(pipelineId, nodeId, nodeType, parameterName, valueString);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildGetParameterDefaultValueMethod() { var sb = new StringBuilder(); sb.AppendLine(" public object? GetParameterDefaultValue(string nodeType, string parameterName)"); sb.AppendLine(" {"); sb.AppendLine(" return _nodeFactory.GetParameterDefaultValue(nodeType, parameterName);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildSetNodeParametersValuesMethod() { var sb = new StringBuilder(); sb.AppendLine( " public void SetNodeParametersValues(string pipelineId, TNode node, string nodeId, Dictionary parameters) where TNode : INode"); sb.AppendLine(" {"); sb.AppendLine(" _nodeFactory.SetNodeParametersValues(pipelineId, node, nodeId, parameters);"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildConnectPortsMethod() { var sb = new StringBuilder(); sb.AppendLine( " public void ConnectPorts(string pipelineId, TNode node, string nodeId, Dictionary inputs, IReadOnlyDictionary createdNodes) where TNode : INode"); sb.AppendLine(" {"); sb.AppendLine(" _nodeFactory.ConnectPorts(pipelineId, node, nodeId, inputs, createdNodes);"); sb.AppendLine(" }"); return sb.ToString(); } }