/* ======================================================================== * Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ namespace Opc.Ua.SourceGeneration { /// /// Template strings /// internal static class NodeStateTemplates { /// /// Main file template for predefined nodes code generation /// public static readonly TemplateString File = TemplateString.Parse( $$""" {{Tokens.CodeHeader}} {{Tokens.ListOfImports}} namespace {{Tokens.NamespacePrefix}} { {{Tokens.ListOfTypes}} {{Tokens.ListOfTypeActivators}} } """); /// /// File template for the model's NodeSet import factory provider /// public static readonly TemplateString NodeSetImportSupport_File = TemplateString.Parse( $$""" {{Tokens.CodeHeader}} #pragma warning disable RCS0056 // A generated identifier can make a line exceed 120 characters namespace {{Tokens.NamespacePrefix}} { {{Tokens.ListOfTypes}} } """); /// /// Main file template for predefined nodes code generation /// public static readonly TemplateString Extensions_File = TemplateString.Parse( $$""" {{Tokens.CodeHeader}} {{Tokens.ListOfImports}} namespace {{Tokens.NamespacePrefix}} { /// /// Extensions that add functionality from the {{Tokens.NamespaceUri}} namespace. /// public static partial class {{Tokens.Namespace}}Extensions { /// /// Creates and returns all node states for the {{Tokens.NamespaceUri}} namespace. /// /// The collection to add the node states to. /// The system context to use for initialization. /// Original collection with node states added. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public static global::Opc.Ua.NodeStateCollection Add{{Tokens.Namespace}}( this global::Opc.Ua.NodeStateCollection nodes, global::Opc.Ua.ISystemContext context) { {{Tokens.ListOfNodeStateInitializers}} return nodes; } /// /// Adds all nodestate activators of the {{Tokens.NamespaceUri}} /// namespace to a INodeStateFactoryBuilder. /// /// The node state factory builder. /// The builder passed as parameter for chaining. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public static global::Opc.Ua.INodeStateFactoryBuilder Add{{Tokens.Namespace}}( this global::Opc.Ua.INodeStateFactoryBuilder builder) { {{Tokens.ListOfActivatorRegistrations}} return builder; } {{Tokens.ListOfNodeStateInstanceFactories}} {{Tokens.ListOfNodeStateTypeFactories}} } } """); /// /// Object Type node state /// public static readonly TemplateString ObjectType_Class = TemplateString.Parse( $$""" /// /// The {{Tokens.ClassName}} ObjectType state. /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public partial class {{Tokens.ClassName}}State : {{Tokens.BaseClassName}}State{{Tokens.BaseT}} { /// /// Initializes a new instance of the class. /// public {{Tokens.ClassName}}State(global::Opc.Ua.NodeState? parent) : base(parent) { } {{Tokens.ElementNamespaceOverride}} {{Tokens.ListOfProperties}} {{Tokens.ListOfNonMandatoryChildren}} /// public override bool DeepEquals(global::Opc.Ua.NodeState node) { if (!(node is {{Tokens.ClassName}}State state) || !base.DeepEquals(state)) { return false; } {{Tokens.ListOfEqualityComparers}} return true; } /// public override int DeepGetHashCode() { int hashCode = base.DeepGetHashCode(); {{Tokens.ListOfChildHashes}} return hashCode; } {{Tokens.ListOfChildOperations}} /// protected override void CopyTo(global::Opc.Ua.NodeState target) { if (!(target is {{Tokens.ClassName}}State state)) { return; } {{Tokens.ListOfChildCopies}} base.CopyTo(target); } /// protected override global::Opc.Ua.NodeState CreateCopy() { return new {{Tokens.ClassName}}State(null); } /// protected override global::Opc.Ua.NodeId GetDefaultTypeDefinitionId( global::Opc.Ua.NamespaceTable namespaceUris) { return global::Opc.Ua.NodeId.Create( global::{{Tokens.NamespacePrefix}}.ObjectTypes.{{Tokens.TypeName}}, {{Tokens.NamespaceUri}}, namespaceUris); } /// protected override void Initialize(global::Opc.Ua.ISystemContext context) { base.Initialize(context); Initialize( context, context.CreateInstanceOf{{Tokens.SymbolicId}}()); InitializeOptionalChildren(context); } /// protected override void Initialize( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState source) { InitializeOptionalChildren(context); base.Initialize(context, source); } /// protected override void InitializeOptionalChildren( global::Opc.Ua.ISystemContext context) { base.InitializeOptionalChildren(context); {{Tokens.InitializeOptionalChildren}} } {{Tokens.ListOfFields}} } """); /// /// Method type node state /// public static readonly TemplateString MethodType_Class = TemplateString.Parse( $$""" /// /// The {{Tokens.ClassName}} MethodType. /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public partial class {{Tokens.ClassName}} : global::Opc.Ua.MethodState { /// /// Initializes a new instance of the class. /// public {{Tokens.ClassName}}(global::Opc.Ua.NodeState? parent) : base(parent) { } /// public new static global::Opc.Ua.NodeState Construct(global::Opc.Ua.NodeState parent) { return new {{Tokens.ClassName}}(parent); } /// public {{Tokens.ClassName}}MethodCallHandler? OnCall; /// public {{Tokens.ClassName}}MethodAsyncCallHandler? OnCallAsync; {{Tokens.ListOfProperties}} {{Tokens.ListOfNonMandatoryChildren}} /// public override bool DeepEquals(global::Opc.Ua.NodeState node) { if (!(node is {{Tokens.ClassName}} state) || !base.DeepEquals(state)) { return false; } {{Tokens.ListOfEqualityComparers}} return true; } /// public override int DeepGetHashCode() { int hashCode = base.DeepGetHashCode(); {{Tokens.ListOfChildHashes}} return hashCode; } {{Tokens.ListOfChildOperations}} /// protected override void CopyTo(global::Opc.Ua.NodeState target) { if (!(target is {{Tokens.ClassName}} state)) { return; } {{Tokens.ListOfChildCopies}} base.CopyTo(target); } /// protected override global::Opc.Ua.NodeState CreateCopy() { return new {{Tokens.ClassName}}(null); } /// protected override void Initialize(global::Opc.Ua.ISystemContext context) { base.Initialize(context); Initialize( context, context.CreateInstanceOf{{Tokens.SymbolicId}}()); InitializeOptionalChildren(context); } /// protected override void InitializeOptionalChildren( global::Opc.Ua.ISystemContext context) { base.InitializeOptionalChildren(context); {{Tokens.InitializeOptionalChildren}} } /// protected override global::Opc.Ua.ServiceResult? Call( global::Opc.Ua.ISystemContext _context, global::Opc.Ua.NodeId _objectId, global::Opc.Ua.ArrayOf _inputArguments, global::System.Collections.Generic.List _outputArguments) { if (OnCall == null) { return base.Call(_context, _objectId, _inputArguments, _outputArguments); } global::Opc.Ua.ServiceResult? _result = null; {{Tokens.ListOfInputArguments}} {{Tokens.ListOfOutputDeclarations}} if (OnCall != null) { {{Tokens.OnCallImplementation}} } {{Tokens.ListOfOutputArguments}} return _result; } /// protected override async global::System.Threading.Tasks.ValueTask CallAsync( global::Opc.Ua.ISystemContext _context, global::Opc.Ua.NodeId _objectId, global::Opc.Ua.ArrayOf _inputArguments, global::System.Collections.Generic.List _outputArguments, global::System.Threading.CancellationToken cancellationToken = default) { if (OnCall == null && OnCallAsync == null) { return await base.CallAsync( _context, _objectId, _inputArguments, _outputArguments, cancellationToken).ConfigureAwait(false); } {{Tokens.ClassName}}Result? _result = null; {{Tokens.ListOfInputArguments}} if (OnCallAsync != null) { {{Tokens.OnCallAsyncImplementation}} } else if (OnCall != null) { return Call(_context, _objectId, _inputArguments, _outputArguments); } {{Tokens.ListOfOutputArgumentsFromResult}} return _result?.ServiceResult; } {{Tokens.ListOfFields}} } /// /// Represents the result of a {{Tokens.ClassName}} method call. /// public partial class {{Tokens.ClassName}}Result { public global::Opc.Ua.ServiceResult ServiceResult { get; set; } {{Tokens.ListOfResultProperties}} } /// /// Handles the {{Tokens.ClassName}} method call. /// public delegate global::Opc.Ua.ServiceResult {{Tokens.ClassName}}MethodCallHandler( {{Tokens.OnCallDeclaration}} /// /// Handles the asynchronous {{Tokens.ClassName}} method call. /// public delegate global::System.Threading.Tasks.ValueTask<{{Tokens.ClassName}}Result> {{Tokens.ClassName}}MethodAsyncCallHandler( {{Tokens.OnCallAsyncDeclaration}} """); /// /// Variable type node state /// public static readonly TemplateString VariableType_Class = TemplateString.Parse( $$""" /// /// The {{Tokens.ClassName}} VariableType state. /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public partial class {{Tokens.ClassName}}State : {{Tokens.BaseClassName}}State{{Tokens.BaseT}} { /// /// Initializes a new instance of the class. /// public {{Tokens.ClassName}}State(global::Opc.Ua.NodeState? parent) : base(parent) { } {{Tokens.ListOfProperties}} {{Tokens.ListOfNonMandatoryChildren}} /// public override bool DeepEquals(global::Opc.Ua.NodeState node) { if (!(node is {{Tokens.ClassName}}State state) || !base.DeepEquals(state)) { return false; } {{Tokens.ListOfEqualityComparers}} return true; } /// public override int DeepGetHashCode() { int hashCode = base.DeepGetHashCode(); {{Tokens.ListOfChildHashes}} return hashCode; } {{Tokens.ListOfChildOperations}} /// protected override void CopyTo(global::Opc.Ua.NodeState target) { if (!(target is {{Tokens.ClassName}}State state)) { return; } {{Tokens.ListOfChildCopies}} base.CopyTo(target); } /// protected override global::Opc.Ua.NodeState CreateCopy() { return new {{Tokens.ClassName}}State(null); } /// protected override global::Opc.Ua.NodeId GetDefaultTypeDefinitionId( global::Opc.Ua.NamespaceTable namespaceUris) { return global::Opc.Ua.NodeId.Create( global::{{Tokens.NamespacePrefix}}.VariableTypes.{{Tokens.TypeName}}, {{Tokens.NamespaceUri}}, namespaceUris); } /// protected override global::Opc.Ua.NodeId GetDefaultDataTypeId( global::Opc.Ua.NamespaceTable namespaceUris) { return global::Opc.Ua.NodeId.Create( global::{{Tokens.DataTypeNamespacePrefix}}.DataTypes.{{Tokens.DataType}}, {{Tokens.DataTypeNamespaceUri}}, namespaceUris); } /// protected override int GetDefaultValueRank() { return {{Tokens.ValueRank}}; } /// protected override void Initialize(global::Opc.Ua.ISystemContext context) { base.Initialize(context); Initialize( context, context.CreateInstanceOf{{Tokens.SymbolicId}}()); // InitializeOptionalChildren(context); } /// protected override void Initialize( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState source) { InitializeOptionalChildren(context); base.Initialize(context, source); } /// protected override void InitializeOptionalChildren( global::Opc.Ua.ISystemContext context) { base.InitializeOptionalChildren(context); {{Tokens.InitializeOptionalChildren}} } {{Tokens.ListOfFields}} } {{Tokens.TypedVariableType}} {{Tokens.VariableTypeValue}} """); /// /// Factory methods for variable states with typed values /// public static readonly TemplateString FactoriesForVariableTypeWithTypedValue = TemplateString.Parse( $$""" /// /// Creates a new instance of the {{Tokens.ClassName}}State class with a built-in value type /// and associated TBuilder to extract the value from the Variant and create a new Variant /// from it. /// public static {{Tokens.ClassName}}State For(global::Opc.Ua.NodeState? parent) where TBuilder : struct, global::Opc.Ua.IVariantBuilder { return new {{Tokens.ClassName}}State.Implementation(parent); } """); /// /// Typed variable type node state /// public static readonly TemplateString VariableTypeWithTypedValue_Class = TemplateString.Parse( $$""" /// /// The {{Tokens.ClassName}} VariableType state. /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public abstract class {{Tokens.ClassName}}State : {{Tokens.ClassName}}State { /// /// Initializes a new instance of the class. /// protected {{Tokens.ClassName}}State(global::Opc.Ua.NodeState? parent) : base(parent) { } /// /// Creates a new instance of the /// class with a built-in value type and associated TBuilder to extract the /// value from the Variant and create a new Variant from it. /// /// The builder to use for T public static {{Tokens.ClassName}}State With( global::Opc.Ua.NodeState? parent = null) where TBuilder : struct, global::Opc.Ua.IVariantBuilder { return new Implementation(parent); } /// public new abstract T Value { get; set; } /// protected override void Initialize(global::Opc.Ua.ISystemContext context) { base.Initialize(context); base.Initialize(context); } /// protected override void Initialize( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState source) { InitializeOptionalChildren(context); base.Initialize(context, source); } /// /// Adds builder which extracts T from Variant or creates new Variant with type T /// This is public so it can be overridden by classes outside of the namespace /// /// The builder to use for T public class Implementation : {{Tokens.ClassName}}State where TBuilder : struct, global::Opc.Ua.IVariantBuilder { /// /// Initializes a new instance of the class. /// public Implementation(global::Opc.Ua.NodeState? parent) : base(parent) { m_builder = new TBuilder(); Value = default(T); } /// public override T Value { get => m_builder.GetValue(WrappedValue); set => WrappedValue = m_builder.WithValue(value); } /// protected override global::Opc.Ua.NodeState CreateCopy() { return new Implementation(Parent); } private readonly TBuilder m_builder; } } """); /// /// Variable type value field methods /// public static readonly TemplateString VariableType_ValueMethods = TemplateString.Parse( $$""" /// /// Handles the read of the {{Tokens.ChildName}} variable. /// private global::Opc.Ua.ServiceResult OnRead_{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState node, global::Opc.Ua.NumericRange indexRange, global::Opc.Ua.QualifiedName dataEncoding, ref global::Opc.Ua.Variant value, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { EnterLock(); try { DoBeforeReadProcessing(context, node); var childVariable = m_variable?.{{Tokens.ChildPath}}; if (childVariable != null && global::Opc.Ua.StatusCode.IsBad(childVariable.StatusCode)) { value = global::Opc.Ua.Variant.Null; statusCode = childVariable.StatusCode; return new global::Opc.Ua.ServiceResult(statusCode); } if (m_value != null) { value = global::Opc.Ua.Variant.{{Tokens.VariantFrom}}( ({{Tokens.ChildDataType}})m_value.{{Tokens.PropertyName}}); } var result = Read( context, node, indexRange, dataEncoding, ref value, ref statusCode, ref timestamp); if (childVariable != null && global::Opc.Ua.ServiceResult.IsNotBad(result)) { timestamp = childVariable.Timestamp; if (statusCode != childVariable.StatusCode) { statusCode = childVariable.StatusCode; result = new global::Opc.Ua.ServiceResult(statusCode); } } return result; } finally { ExitLock(); } } /// /// Handles the write of the {{Tokens.ChildName}} variable. /// private global::Opc.Ua.ServiceResult OnWrite_{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState node, global::Opc.Ua.NumericRange indexRange, global::Opc.Ua.QualifiedName dataEncoding, ref global::Opc.Ua.Variant value, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { EnterLock(); try { if (!value.{{Tokens.VariantTryGet}}(out {{Tokens.ChildDataType}} newValue)) { newValue = default; } UpdateChildVariableStatus(m_variable.{{Tokens.ChildPath}}, ref statusCode, ref timestamp); m_value.{{Tokens.PropertyName}} = {{Tokens.ValueWrite}}; UpdateParent(context, ref statusCode, ref timestamp); } finally { ExitLock(); } return global::Opc.Ua.ServiceResult.Good; } """); /// /// Variable type node state /// public static readonly TemplateString VariableTypeValue_Class = TemplateString.Parse( $$""" /// /// The {{Tokens.ClassName}} VariableType value. /// [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public class {{Tokens.ClassName}}Value : global::Opc.Ua.BaseVariableValue { /// /// Initializes a new instance of the class. /// public {{Tokens.ClassName}}Value( {{Tokens.ClassName}}State variable, {{Tokens.DataType}}? value, global::System.Threading.Lock? dataLock) : base(dataLock) { m_value = value; if (m_value == null) { m_value = new {{Tokens.DataType}}(); } Initialize(variable); } /// /// Gets the variable associated with the value. /// public {{Tokens.ClassName}}State Variable => m_variable; /// /// Gets or sets the value. /// public {{Tokens.DataType}} Value { get => m_value; set => m_value = value; } /// /// Initializes the value. /// private void Initialize({{Tokens.ClassName}}State variable) { EnterLock(); try { m_variable = variable; variable.Value = m_value; variable.OnReadValue = OnReadValue; variable.OnWriteValue = OnWriteValue; global::Opc.Ua.BaseVariableState? instance = null; global::System.Collections.Generic.List updateList = new global::System.Collections.Generic.List(); updateList.Add(variable); {{Tokens.ListOfChildInitializers}} SetUpdateList(updateList); } finally { ExitLock(); } } /// protected global::Opc.Ua.ServiceResult OnReadValue( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState node, global::Opc.Ua.NumericRange indexRange, global::Opc.Ua.QualifiedName dataEncoding, ref global::Opc.Ua.Variant value, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { EnterLock(); try { DoBeforeReadProcessing(context, node); if (m_value != null) { value = global::Opc.Ua.Variant.{{Tokens.VariantFrom}}(m_value); } return Read(context, node, indexRange, dataEncoding, ref value, ref statusCode, ref timestamp); } finally { ExitLock(); } } /// private global::Opc.Ua.ServiceResult OnWriteValue( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState node, global::Opc.Ua.NumericRange indexRange, global::Opc.Ua.QualifiedName dataEncoding, ref global::Opc.Ua.Variant value, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { EnterLock(); try { if (!value.{{Tokens.VariantTryGet}}(out {{Tokens.DataType}} newValue)) { newValue = default; } if ({{Tokens.ValueComparison}}) { UpdateChildrenChangeMasks(context, ref newValue, ref statusCode, ref timestamp); Timestamp = timestamp; m_value = {{Tokens.ValueWrite}}; m_variable.UpdateChangeMasks(global::Opc.Ua.NodeStateChangeMasks.Value); } } finally { ExitLock(); } return global::Opc.Ua.ServiceResult.Good; } /// /// Updates the change masks for the children. /// private void UpdateChildrenChangeMasks( global::Opc.Ua.ISystemContext context, ref {{Tokens.DataType}} newValue, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { {{Tokens.ListOfUpdateChildrenChangeMasks}} } /// /// Updates the parent variable status. /// private void UpdateParent( global::Opc.Ua.ISystemContext context, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { Timestamp = timestamp; m_variable.UpdateChangeMasks(global::Opc.Ua.NodeStateChangeMasks.Value); m_variable.ClearChangeMasks(context, false); } /// /// Updates the status of a child variable. /// private void UpdateChildVariableStatus( global::Opc.Ua.BaseVariableState child, ref global::Opc.Ua.StatusCode statusCode, ref global::Opc.Ua.DateTimeUtc timestamp) { if (child == null) { return; } child.StatusCode = statusCode; if (timestamp == global::Opc.Ua.DateTimeUtc.MinValue) { timestamp = global::Opc.Ua.DateTimeUtc.Now; } child.Timestamp = timestamp; } {{Tokens.ListOfChildMethods}} private {{Tokens.DataType}}? m_value; private {{Tokens.ClassName}}State? m_variable; } """); /// /// Initialize optional child /// public static readonly TemplateString InitializeOptionalChild = TemplateString.Parse( $$""" if ({{Tokens.ChildName}} != null && global::Opc.Ua.NodeState.NeedsOptionalInitialization({{Tokens.ChildName}})) { {{Tokens.ChildName}}.Create( context, context.Create{{Tokens.SymbolicId}}(this, true)); } """); /// /// Property template /// public static readonly TemplateString Property = TemplateString.Parse( $$""" /// /// {{Tokens.ChildName}} property /// {{Tokens.AccessorSymbol}} {{Tokens.ClassName}}? {{Tokens.ChildName}} { get => {{Tokens.FieldName}}; set { if (!object.ReferenceEquals({{Tokens.FieldName}}, value)) { ChangeMasks |= global::Opc.Ua.NodeStateChangeMasks.Children; } {{Tokens.FieldName}} = value; } } """); /// /// Override property template /// public static readonly TemplateString PropertyOverride = TemplateString.Parse( $$""" /// /// {{Tokens.ChildName}} property /// {{Tokens.AccessorSymbol}} {{Tokens.ClassName}}? {{Tokens.ChildName}} { get => ({{Tokens.ClassName}})base.{{Tokens.ChildName}}; set => base.{{Tokens.ChildName}} = value; } """); /// /// Add Optional component template /// public static readonly TemplateString OptionalMethod = TemplateString.Parse( $$""" /// /// Adds the optional {{Tokens.ChildName}} child and returns this /// instance so calls can be chained, e.g. /// parent.Add{{Tokens.ChildName}}(context).Add{{Tokens.ChildName}}Other(context).... /// Idempotent: if {{Tokens.ChildName}} already exists the existing /// child is kept and only its NodeId is overwritten (when a /// non-null is supplied). /// /// The system context. /// /// Optional NodeId for the newly-added child. When /// (the default), the /// child keeps the type-level NodeId assigned by the generated /// factory unless 's /// is /// non-null, in which case a fresh NodeId is minted via the /// factory. /// {{Tokens.AccessorSymbol}} {{Tokens.OwnerClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeId nodeId = default) { if ({{Tokens.ChildName}} == null) { {{Tokens.ClassName}} state = context.Create{{Tokens.SymbolicId}}(this, true); {{Tokens.ChildName}} = state; global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.NodeId previousNodeId = nodeState.NodeId; if (!nodeId.IsNull) { nodeState.NodeId = nodeId; global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, state, previousNodeId, this); } else if (context.NodeIdFactory != null && nodeState.NodeId.Equals({{Tokens.NodeIdConstant}})) { previousNodeId = global::Opc.Ua.NodeInstanceExtensions.AssignInstanceNodeId(context, state); global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, state, previousNodeId, this); } } else if (!nodeId.IsNull) { ((global::Opc.Ua.NodeState){{Tokens.ChildName}}).NodeId = nodeId; } return this; } /// /// Adds the optional {{Tokens.ChildName}} child and invokes /// on the (just-added or pre-existing) /// typed child. Returns this instance for fluent chaining. /// /// The system context. /// /// Mutates the typed child in-place. Invoked after the child slot /// is materialised so the callback can rely on the typed child /// being non-null. /// /// /// Optional NodeId for the newly-added child. See the /// /// overload for the default behaviour. /// public {{Tokens.OwnerClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::System.Action<{{Tokens.ClassName}}> configure, global::Opc.Ua.NodeId nodeId = default) { Add{{Tokens.ChildName}}(context, nodeId); configure({{Tokens.ChildName}}!); return this; } /// /// Conditionally adds the optional {{Tokens.ChildName}} child /// and invokes on the typed child. /// When is false the child /// is not materialised and the callback is not invoked. /// Returns this instance for fluent chaining. /// /// The system context. /// /// Whether to add and configure the child. When false, /// the call is a no-op. /// /// /// Mutates the typed child in-place. Only invoked when /// is true. /// /// /// Optional NodeId for the newly-added child. /// public {{Tokens.OwnerClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, bool condition, global::System.Action<{{Tokens.ClassName}}> configure, global::Opc.Ua.NodeId nodeId = default) { if (!condition) { return this; } Add{{Tokens.ChildName}}(context, nodeId); configure({{Tokens.ChildName}}!); return this; } /// /// Adds the optional {{Tokens.ChildName}} child and invokes the /// transform on the typed child; the /// callback's return value replaces the typed slot (so the /// caller can wrap or substitute the child). Returns this /// instance for fluent chaining. /// /// The system context. /// /// Transforms the typed child. The returned instance is stored /// in the typed slot; pass back the same instance to keep it /// unchanged or a new instance to replace it. /// /// /// Optional NodeId for the newly-added child. /// public {{Tokens.OwnerClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::System.Func<{{Tokens.ClassName}}, {{Tokens.ClassName}}> configure, global::Opc.Ua.NodeId nodeId = default) { Add{{Tokens.ChildName}}(context, nodeId); {{Tokens.ChildName}} = configure({{Tokens.ChildName}}!); return this; } /// /// Conditionally adds the optional {{Tokens.ChildName}} child and /// invokes the transform on the /// typed child. When is false /// the child is not materialised and the callback is not invoked. /// Returns this instance for fluent chaining. /// /// The system context. /// /// Whether to add and configure the child. When false, /// the call is a no-op. /// /// /// Transforms the typed child. Only invoked when /// is true. /// /// /// Optional NodeId for the newly-added child. /// public {{Tokens.OwnerClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, bool condition, global::System.Func<{{Tokens.ClassName}}, {{Tokens.ClassName}}> configure, global::Opc.Ua.NodeId nodeId = default) { if (!condition) { return this; } Add{{Tokens.ChildName}}(context, nodeId); {{Tokens.ChildName}} = configure({{Tokens.ChildName}}!); return this; } """); /// /// Place holder method template /// public static readonly TemplateString PlaceHolderMethod = TemplateString.Parse( $$""" /// /// Add a placeholder {{Tokens.ChildName}} as child /// {{Tokens.AccessorSymbol}} {{Tokens.ClassName}} Add{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::Opc.Ua.QualifiedName browseName) { {{Tokens.ClassName}} state = context.Create{{Tokens.SymbolicId}}(this, browseName); ReplaceChild(context, state); return state; } """); /// /// Find child methods /// public static readonly TemplateString ChildOperations = TemplateString.Parse( $$""" /// public override void GetChildren( global::Opc.Ua.ISystemContext context, global::System.Collections.Generic.IList children) { {{Tokens.ListOfFindChildren}} base.GetChildren(context, children); } {{Tokens.ListOfCreateOrReplaceChild}} /// protected override global::Opc.Ua.BaseInstanceState? FindChild( global::Opc.Ua.ISystemContext context, global::Opc.Ua.QualifiedName browseName, bool createOrReplace, global::Opc.Ua.BaseInstanceState? replacement, bool assignInstanceNodeIds = true) { global::Opc.Ua.BaseInstanceState? instance = null; switch (browseName.Name) { {{Tokens.ListOfFindChildCase}} } if (instance != null) { return instance; } return base.FindChild( context, browseName, createOrReplace, replacement, assignInstanceNodeIds); } /// protected override void RemoveExplicitlyDefinedChild(global::Opc.Ua.BaseInstanceState child) { {{Tokens.ListOfRemoveChild}} base.RemoveExplicitlyDefinedChild(child); } """); /// /// Find child case template. Uses a literal string with the /// runtime browse name (which may differ from the symbolic /// name when the design overrides <opc:BrowseName>, /// as in Boiler.InputPipe → "PipeX001"). /// Avoids depending on {Namespace}.BrowseNames.{ChildName} /// constants so cross-namespace inherited children compile /// even when the foreign namespace's generated /// BrowseNames class doesn't carry a constant for that /// name. /// public static readonly TemplateString FindChildCase = TemplateString.Parse( $$""" case "{{Tokens.ChildBrowseNameLiteral}}": { instance = !createOrReplace ? {{Tokens.ChildName}} : CreateOrReplace{{Tokens.ChildName}}( context, replacement, assignInstanceNodeIds); break; } """); /// /// Create or replace a child on the class. The optional /// assignInstanceNodeIds parameter lets the generated type and /// child factories opt out of per-instance NodeId assignment: they /// build declaration subtrees whose NodeIds must stay at their /// type-level values (the enclosing /// CreateInstanceOf<Type> factory rebases the finished /// subtree in one pass). Every other caller - the generated /// FindChild plumbing behind NodeState.CreateChild / /// NodeState.ReplaceChild and hand-written node managers - /// materialises children onto an already-instantiated tree and /// therefore gets per-instance NodeIds by default. /// public static readonly TemplateString CreateOrReplaceChild = TemplateString.Parse( $$""" /// /// Create or replace the mandatory {{Tokens.ChildName}} child /// /// The system context. /// /// The child to adopt or to copy onto the existing child. When /// null a new child is created. /// /// /// When true (the default) and the context supplies a /// , a /// child that still carries a null or type-level NodeId - and its /// descendants - are rebased onto per-instance NodeIds so multiple /// instances of the same type never collide. A NodeId the caller /// already assigned is never overwritten. /// {{Tokens.AccessorSymbol}} {{Tokens.ClassName}} CreateOrReplace{{Tokens.ChildName}}( global::Opc.Ua.ISystemContext context, global::Opc.Ua.BaseInstanceState? replacement, bool assignInstanceNodeIds = true) { if (replacement is {{Tokens.ClassName}} typedReplacement) { // a replacement of the matching type is used directly, // replacing any child that may already exist. {{Tokens.ChildName}} = typedReplacement; } else if ({{Tokens.ChildName}} == null) { {{Tokens.ClassName}} child = {{Tokens.ClassFactory}}(this); // Stamp the child's identity so a path based NodeIdFactory // can derive a per-instance NodeId for it below, and so // NodeState.CreateChild returns a child that carries the // browse name it was asked for. global::Opc.Ua.NodeState childNode = child; childNode.SymbolicName = "{{Tokens.BrowseNameLiteral}}"; childNode.DisplayName = new global::Opc.Ua.LocalizedText( "{{Tokens.ChildBrowseNameLiteral}}"); if (context.NamespaceUris != null) { childNode.BrowseName = new global::Opc.Ua.QualifiedName( "{{Tokens.ChildBrowseNameLiteral}}", context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); } if (replacement != null) { child.Create(context, replacement); } {{Tokens.ChildName}} = child; } else if (replacement != null) { // an existing child is replaced by copying the replacement // onto it, keeping the strongly typed instance. {{Tokens.ChildName}}.Create(context, replacement); } if (assignInstanceNodeIds && context.NodeIdFactory != null) { global::Opc.Ua.NodeState childState = {{Tokens.ChildName}}; if (childState.NodeId.IsNull || childState.NodeId.Equals({{Tokens.NodeIdConstant}})) { global::Opc.Ua.NodeId previousNodeId = global::Opc.Ua.NodeInstanceExtensions.AssignInstanceNodeId( context, childState); global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, childState, previousNodeId, this); } } return {{Tokens.ChildName}}; } """); /// /// Find children method template /// public static readonly TemplateString FindChildren = TemplateString.Parse( $$""" if ({{Tokens.FieldName}} != null) { children.Add({{Tokens.FieldName}}); } """); /// /// Remove child template /// public static readonly TemplateString RemoveChild = TemplateString.Parse( $$""" if (object.ReferenceEquals({{Tokens.FieldName}}, child)) { {{Tokens.FieldName}} = null; return; } """); /// /// Clone child template /// public static readonly TemplateString CloneChild = TemplateString.Parse( $$""" state.{{Tokens.BrowseName}} = global::Opc.Ua.NodeState.CloneChild({{Tokens.BrowseName}}, state); """); /// /// Compare child template /// public static readonly TemplateString CompareChild = TemplateString.Parse( $$""" if (!global::Opc.Ua.NodeStateComparer.Default.Equals( state.{{Tokens.BrowseName}}, {{Tokens.BrowseName}})) { return false; } """); /// /// Hash child template /// public static readonly TemplateString HashChild = TemplateString.Parse( $$""" hashCode = (hashCode * 16777619) ^ global::Opc.Ua.NodeStateComparer.Default.GetHashCode({{Tokens.BrowseName}}); """); /// /// Encodeable activator /// public static readonly TemplateString ActivatorClass = TemplateString.Parse( $$""" [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{Tokens.Tool}}", "{{Tokens.Version}}")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()] public sealed class {{Tokens.StateClassName}}Activator : global::Opc.Ua.NodeStateActivator { /// /// The singleton instance of the activator. /// public static readonly {{Tokens.StateClassName}}Activator Instance = new {{Tokens.StateClassName}}Activator(); /// protected override global::Opc.Ua.NodeState CreateInstance( global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent) { return context.CreateInstanceOf{{Tokens.SymbolicId}}(parent); } } """); /// /// Nodestate activator registration /// public static readonly TemplateString ActivatorRegistration = TemplateString.Parse( $$""" // Register node state factory for {{Tokens.BrowseName}} {{Tokens.NodeClass}} builder = builder.RegisterType( {{Tokens.NodeClass}}Ids.{{Tokens.SymbolicId}}, {{Tokens.StateClassName}}Activator.Instance); """); /// /// Template for a single node state creation call /// public static readonly TemplateString Add = TemplateString.Parse( $$""" // Add {{Tokens.SymbolicName}} predefined node { global::Opc.Ua.NodeState state = Create{{Tokens.SymbolicId}}(context); state.CreateAsPredefinedNode(context); nodes.Add(state); } """); /// /// Template for a single method state creation call. /// public static readonly TemplateString AddMethod = TemplateString.Parse( $$""" // Add {{Tokens.SymbolicName}} predefined node { global::Opc.Ua.NodeState state = context.CreateInstanceOf{{Tokens.SymbolicId}}(); state.CreateAsPredefinedNode(context); nodes.Add(state); } """); /// /// Template for BaseObjectTypeState creation /// public static readonly TemplateString Create_ObjectType = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} ObjectType node state. /// internal static global::Opc.Ua.BaseObjectTypeState Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = false) { var state = new global::Opc.Ua.BaseObjectTypeState(); global::Opc.Ua.NodeState nodeState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; state.SuperTypeId = {{Tokens.SuperTypeId}}; state.IsAbstract = {{Tokens.IsAbstract}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { nodeState.IsPartOfTypeHierarchy = true; {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for BaseDataVariableTypeState creation /// public static readonly TemplateString Create_VariableType = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} VariableType node state. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseVariableTypeState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.SuperTypeId = {{Tokens.SuperTypeId}}; baseState.IsAbstract = {{Tokens.IsAbstract}}; baseState.DataType = {{Tokens.DataTypeIdConstant}}; baseState.ValueRank = {{Tokens.ValueRank}}; {{Tokens.ArrayDimensions}} {{Tokens.ValueCode}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { nodeState.IsPartOfTypeHierarchy = true; {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for ReferenceTypeState creation /// public static readonly TemplateString Create_ReferenceType = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} ReferenceType node state. /// internal static global::Opc.Ua.ReferenceTypeState Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = false) { var state = new global::Opc.Ua.ReferenceTypeState(); global::Opc.Ua.NodeState nodeState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; state.SuperTypeId = {{Tokens.SuperTypeId}}; state.IsAbstract = {{Tokens.IsAbstract}}; state.Symmetric = {{Tokens.SymmetricValue}}; {{Tokens.InverseNameValue}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for DataTypeState creation /// public static readonly TemplateString Create_DataType = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} DataType node state. /// internal static global::Opc.Ua.DataTypeState Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = false) { var state = new global::Opc.Ua.DataTypeState(); global::Opc.Ua.NodeState nodeState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; state.SuperTypeId = {{Tokens.SuperTypeId}}; state.IsAbstract = {{Tokens.IsAbstract}}; state.DataTypeDefinition = {{Tokens.DataTypeDefinition}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for BaseObjectState creation /// public static readonly TemplateString Create_Object = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} Object node state. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = true) { var state = {{Tokens.StateClassFactory}}(null); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseObjectState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; baseState.NumericId = {{Tokens.NumericIdValue}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; // {{Tokens.ModellingRuleId}} baseState.EventNotifier = {{Tokens.EventNotifier}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for BaseVariableState (Property or DataVariable) creation /// public static readonly TemplateString Create_Variable = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} Variable node state. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = true) { var state = {{Tokens.StateClassFactory}}(null); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseVariableState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; baseState.NumericId = {{Tokens.NumericIdValue}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; // {{Tokens.ModellingRuleId}} baseState.DataType = {{Tokens.DataTypeIdConstant}}; baseState.ValueRank = {{Tokens.ValueRank}}; {{Tokens.ArrayDimensions}} baseState.AccessLevel = {{Tokens.AccessLevelValue}}; baseState.UserAccessLevel = {{Tokens.UserAccessLevelValue}}; baseState.MinimumSamplingInterval = {{Tokens.MinimumSamplingIntervalValue}}; baseState.Historizing = {{Tokens.HistorizingValue}}; {{Tokens.ValueCode}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for ViewState creation /// public static readonly TemplateString Create_View = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} View node state. /// internal static global::Opc.Ua.ViewState Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, bool forInstance = true) { var state = new global::Opc.Ua.ViewState(); global::Opc.Ua.NodeState nodeState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText({{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; state.EventNotifier = {{Tokens.EventNotifier}}; state.ContainsNoLoops = {{Tokens.ContainsNoLoopsValue}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for MethodState creation /// public static readonly TemplateString Create_InstanceOfMethodType = TemplateString.Parse( $$""" /// /// Creates an instance of the {{Tokens.SymbolicName}} Method node state. /// /// /// The returned node graph has not completed its create lifecycle. /// Node manager registration completes it automatically. Call /// /// before registration when configuration depends on /// OnBeforeCreate or OnAfterCreate. /// public static {{Tokens.StateClassName}} CreateInstanceOf{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent = null, global::Opc.Ua.QualifiedName browseName = default) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.MethodState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); } else { nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } {{Tokens.MethodDeclarationId}} {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.Executable = {{Tokens.ExecutableValue}}; baseState.UserExecutable = {{Tokens.ExecutableValue}}; {{Tokens.ListOfInputArguments}} {{Tokens.ListOfOutputArguments}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!browseName.IsNull && context.NodeIdFactory != null) { global::Opc.Ua.NodeId previousNodeId = global::Opc.Ua.NodeInstanceExtensions.AssignInstanceNodeId(context, state); global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, state, previousNodeId); } return state; } """); /// /// Creates a MethodState InputArguments or OutputArguments property. /// public static readonly TemplateString Create_MethodArguments = TemplateString.Parse( $$""" global::Opc.Ua.PropertyState> {{Tokens.PropertyName}} = state.CreateOrReplace{{Tokens.BrowseName}}(context, null, assignInstanceNodeIds: false); {{Tokens.PropertyName}}.SymbolicName = global::Opc.Ua.BrowseNames.{{Tokens.BrowseName}}; {{Tokens.PropertyName}}.BrowseName = global::Opc.Ua.QualifiedName.From(global::Opc.Ua.BrowseNames.{{Tokens.BrowseName}}); {{Tokens.PropertyName}}.DisplayName = new global::Opc.Ua.LocalizedText(global::Opc.Ua.BrowseNames.{{Tokens.BrowseName}}); {{Tokens.PropertyName}}.TypeDefinitionId = global::Opc.Ua.VariableTypeIds.PropertyType; {{Tokens.PropertyName}}.ReferenceTypeId = global::Opc.Ua.ReferenceTypeIds.HasProperty; {{Tokens.PropertyName}}.ModellingRuleId = new global::Opc.Ua.NodeId(global::Opc.Ua.Objects.ModellingRule_Mandatory); {{Tokens.PropertyName}}.DataType = global::Opc.Ua.DataTypeIds.Argument; {{Tokens.PropertyName}}.ValueRank = global::Opc.Ua.ValueRanks.OneDimension; {{Tokens.PropertyName}}.ArrayDimensions = global::Opc.Ua.ArrayOf.Wrapped(0u); {{Tokens.PropertyName}}.Value = global::Opc.Ua.ArrayOf.ToArrayOf( new global::Opc.Ua.Argument[] { {{Tokens.ListOfValues}} }); """); /// /// Overrides the value of an existing MethodState InputArguments or /// OutputArguments property while leaving the identity of the property /// node created by its own child factory untouched. /// public static readonly TemplateString Assign_MethodArgumentValues = TemplateString.Parse( $$""" global::Opc.Ua.PropertyState> {{Tokens.PropertyName}} = state.CreateOrReplace{{Tokens.BrowseName}}(context, null, assignInstanceNodeIds: false); {{Tokens.PropertyName}}.Value = global::Opc.Ua.ArrayOf.ToArrayOf( new global::Opc.Ua.Argument[] { {{Tokens.ListOfValues}} }); """); /// /// Template for object type instance creation (instantiate an object type) /// public static readonly TemplateString Create_InstanceOfObjectType = TemplateString.Parse( $$""" /// /// Creates an instance of the {{Tokens.TypeName}} type. /// /// /// The returned node graph has not completed its create lifecycle. /// Node manager registration completes it automatically. Call /// /// before registration when configuration depends on /// OnBeforeCreate or OnAfterCreate. /// public static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent = null, global::Opc.Ua.QualifiedName browseName = default) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseObjectState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); } else { nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.EventNotifier = {{Tokens.EventNotifier}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!browseName.IsNull && context.NodeIdFactory != null) { global::Opc.Ua.NodeId previousNodeId = global::Opc.Ua.NodeInstanceExtensions.AssignInstanceNodeId(context, state); global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, state, previousNodeId); } return state; } """); /// /// Template variable type instance creation (instantiate a variable type) /// public static readonly TemplateString Create_InstanceOfVariableType = TemplateString.Parse( $$""" /// /// Creates an instance of the {{Tokens.TypeName}} variable type. /// /// /// The returned node graph has not completed its create lifecycle. /// Node manager registration completes it automatically. Call /// /// before registration when configuration depends on /// OnBeforeCreate or OnAfterCreate. /// public static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent = null, global::Opc.Ua.QualifiedName browseName = default) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseVariableState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); } else { nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; {{Tokens.ModellingRuleId}} baseState.DataType = {{Tokens.DataTypeIdConstant}}; baseState.ValueRank = {{Tokens.ValueRank}}; {{Tokens.ArrayDimensions}} baseState.AccessLevel = {{Tokens.AccessLevelValue}}; baseState.UserAccessLevel = {{Tokens.UserAccessLevelValue}}; baseState.MinimumSamplingInterval = {{Tokens.MinimumSamplingIntervalValue}}; baseState.Historizing = {{Tokens.HistorizingValue}}; {{Tokens.ValueCode}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!browseName.IsNull && context.NodeIdFactory != null) { global::Opc.Ua.NodeId previousNodeId = global::Opc.Ua.NodeInstanceExtensions.AssignInstanceNodeId(context, state); global::Opc.Ua.NodeInstanceExtensions.AssignInstanceChildNodeIds( context, state, previousNodeId); } return state; } """); /// /// Template for child object state creation /// public static readonly TemplateString Create_ChildObject = TemplateString.Parse( $$""" /// /// Creates an instance of the {{Tokens.SymbolicName}} object node child component. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseObjectState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; {{Tokens.InstanceNodeIdOverride}} baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); baseState.NumericId = {{Tokens.NumericIdValue}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.EventNotifier = {{Tokens.EventNotifier}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for child variable state creation /// public static readonly TemplateString Create_ChildVariable = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} child Variable node child component. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseVariableState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; {{Tokens.InstanceNodeIdOverride}} baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; baseState.NumericId = {{Tokens.NumericIdValue}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.DataType = {{Tokens.DataTypeIdConstant}}; baseState.ValueRank = {{Tokens.ValueRank}}; {{Tokens.ArrayDimensions}} baseState.AccessLevel = {{Tokens.AccessLevelValue}}; baseState.UserAccessLevel = {{Tokens.UserAccessLevelValue}}; baseState.MinimumSamplingInterval = {{Tokens.MinimumSamplingIntervalValue}}; baseState.Historizing = {{Tokens.HistorizingValue}}; {{Tokens.ValueCode}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} {{Tokens.MethodDeclarationId}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for child method state creation /// public static readonly TemplateString Create_ChildMethod = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} child Method node child component. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.MethodState baseState = state; nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.NodeId = {{Tokens.NodeIdConstant}}; {{Tokens.InstanceNodeIdOverride}} {{Tokens.MethodDeclarationId}} nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); baseState.NumericId = {{Tokens.NumericIdValue}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.Executable = {{Tokens.ExecutableValue}}; baseState.UserExecutable = {{Tokens.ExecutableValue}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} {{Tokens.ListOfInputArguments}} {{Tokens.ListOfOutputArguments}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for child object state creation /// public static readonly TemplateString Create_ChildObject_Placeholder = TemplateString.Parse( $$""" /// /// Creates an instance of the {{Tokens.SymbolicName}} object placeholder child. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, global::Opc.Ua.QualifiedName browseName = default, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseObjectState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); forInstance = true; } else { // Create the state for the type parent nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } baseState.NumericId = {{Tokens.NumericIdValue}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.EventNotifier = {{Tokens.EventNotifier}}; {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for child variable state creation /// public static readonly TemplateString Create_ChildVariable_Placeholder = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} child Variable object placeholder child. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, global::Opc.Ua.QualifiedName browseName = default, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.BaseVariableState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); forInstance = true; } else { // Create the state for the type parent nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } baseState.NumericId = {{Tokens.NumericIdValue}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.TypeDefinitionId = {{Tokens.TypeDefinitionId}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; {{Tokens.ModellingRuleId}} baseState.DataType = {{Tokens.DataTypeIdConstant}}; baseState.ValueRank = {{Tokens.ValueRank}}; {{Tokens.ArrayDimensions}} baseState.AccessLevel = {{Tokens.AccessLevelValue}}; baseState.UserAccessLevel = {{Tokens.UserAccessLevelValue}}; baseState.MinimumSamplingInterval = {{Tokens.MinimumSamplingIntervalValue}}; baseState.Historizing = {{Tokens.HistorizingValue}}; {{Tokens.ValueCode}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for child method state creation /// public static readonly TemplateString Create_ChildMethod_Placeholder = TemplateString.Parse( $$""" /// /// Creates the {{Tokens.SymbolicName}} child Method object placeholder child. /// internal static {{Tokens.StateClassName}} Create{{Tokens.SymbolicId}}( this global::Opc.Ua.ISystemContext context, global::Opc.Ua.NodeState parent, global::Opc.Ua.QualifiedName browseName = default, bool forInstance = false) { var state = {{Tokens.StateClassFactory}}(parent); global::Opc.Ua.NodeState nodeState = state; global::Opc.Ua.MethodState baseState = state; nodeState.NodeId = {{Tokens.NodeIdConstant}}; if (!browseName.IsNull) { nodeState.SymbolicName = browseName.Name; nodeState.BrowseName = browseName; nodeState.DisplayName = new global::Opc.Ua.LocalizedText(browseName.Name); forInstance = true; } else { // Create the state for the type parent nodeState.SymbolicName = {{Tokens.SymbolicNameSymbol}}; nodeState.BrowseName = new global::Opc.Ua.QualifiedName( {{Tokens.BrowseNameSymbol}}, context.NamespaceUris.GetIndexOrAppend({{Tokens.BrowseNameNamespaceUri}})); nodeState.DisplayName = new global::Opc.Ua.LocalizedText( {{Tokens.DisplayName}}); } baseState.NumericId = {{Tokens.NumericIdValue}}; {{Tokens.DescriptionValue}} nodeState.WriteMask = {{Tokens.WriteMaskValue}}; nodeState.UserWriteMask = {{Tokens.UserWriteMaskValue}}; baseState.ReferenceTypeId = {{Tokens.ReferenceTypeId}}; baseState.Executable = {{Tokens.ExecutableValue}}; baseState.UserExecutable = {{Tokens.ExecutableValue}}; {{Tokens.MethodDeclarationId}} {{Tokens.ReleaseStatusValue}} {{Tokens.CategoriesValue}} {{Tokens.SpecificationValue}} {{Tokens.AccessRestrictionsValue}} {{Tokens.ListOfRolePermissions}} {{Tokens.ListOfReferences}} {{Tokens.ListOfChildNodeStates}} {{Tokens.ListOfInputArguments}} {{Tokens.ListOfOutputArguments}} if (!forInstance) { {{Tokens.ModellingRuleId}} {{Tokens.ListOfOptionalChildNodeStates}} } return state; } """); /// /// Template for role permissions collection initialization /// public static readonly TemplateString ListOfRolePermissions = TemplateString.Parse( $$""" nodeState.RolePermissions = new global::Opc.Ua.RolePermissionType[] { {{Tokens.ListOfRolePermissions}} }; """); /// /// Wrapper template for the singleton-instance NodeId override /// emitted right after the type-level nodeState.NodeId /// assignment in Create_ChildObject / Create_ChildVariable /// / Create_ChildMethod. Renders only when at least one /// singleton-instance branch is collected; otherwise the token /// expands to nothing. /// public static readonly TemplateString InstanceNodeIdOverride = TemplateString.Parse( $$""" if (forInstance && parent != null) { {{Tokens.ListOfInstanceNodeIdBranches}} } """); /// /// One per-singleton branch of the singleton-instance /// nodeState.NodeId override dispatch. Rebinds /// nodeState.NodeId to /// when the parent owner matches . /// public static readonly TemplateString InstanceNodeIdBranch = TemplateString.Parse( $$""" {{Tokens.IfOrElseIf}} (parent.NodeId.Equals({{Tokens.ParentNodeIdConstant}})) { nodeState.NodeId = {{Tokens.NodeIdConstant}}; } """); /// /// Template for role permission /// public static readonly TemplateString RolePermission = TemplateString.Parse( $$""" new global::Opc.Ua.RolePermissionType { RoleId = {{Tokens.RoleIdConstant}}, Permissions = {{Tokens.PermissionsValue}} }, """); /// /// Template for description assignment /// public static readonly TemplateString Description = TemplateString.Parse( $$""" nodeState.Description = new global::Opc.Ua.LocalizedText({{Tokens.DescriptionValue}}); """); /// /// Template for inverse name assignment /// public static readonly TemplateString InverseName = TemplateString.Parse( $$""" state.InverseName = new global::Opc.Ua.LocalizedText({{Tokens.InverseNameValue}}); """); /// /// Template for release status assignment /// public static readonly TemplateString ReleaseStatus = TemplateString.Parse( $$""" nodeState.ReleaseStatus = {{Tokens.ReleaseStatusValue}}; """); /// /// Template for categories assignment /// public static readonly TemplateString Categories = TemplateString.Parse( $$""" nodeState.Categories = {{Tokens.CategoriesValue}}; """); /// /// Template for specification assignment /// public static readonly TemplateString Specification = TemplateString.Parse( $$""" nodeState.Specification = {{Tokens.SpecificationValue}}; """); /// /// Template for access restrictions assignment /// public static readonly TemplateString AccessRestrictions = TemplateString.Parse( $$""" nodeState.AccessRestrictions = {{Tokens.AccessRestrictionsValue}}; """); /// /// Template for method declaration id assignment /// public static readonly TemplateString MethodDeclarationId = TemplateString.Parse( $$""" baseState.MethodDeclarationId = {{Tokens.MethodDeclarationId}}; """); /// /// Template for array dimensions assignment /// public static readonly TemplateString ArrayDimensions = TemplateString.Parse( $$""" baseState.ArrayDimensions = {{Tokens.ArrayDimensions}}; """); /// /// Template for value assignment /// public static readonly TemplateString VariantArrayOfValue = TemplateString.Parse( $$""" baseState.WrappedValue = global::Opc.Ua.Variant.FromStructure( global::Opc.Ua.ArrayOf.ToArrayOf(new {{Tokens.DataType}}[] { {{Tokens.ListOfValues}} })); """); /// /// Template for value assignment /// public static readonly TemplateString ArgumentValue = TemplateString.Parse( $$""" new global::Opc.Ua.Argument { Name = {{Tokens.Name}}, DataType = {{Tokens.DataType}}, ValueRank = {{Tokens.ValueRank}}, ArrayDimensions = {{Tokens.ArrayDimensions}}, Description = {{Tokens.Description}} }, """); } }