Immutable built in types and code generation (#3534)

Generate stack and application code using source generators
Change built in types to readonly structs
  Update localized text implementation to use JSON text serializer
  Status code with symbolic names
  Immutable node ids
  No boxing for all built in types <= 8 bytes in Variant.
Split user identity token and token handling via token handler
Add migration guide for breaking changes
This commit is contained in:
Marc Schier
2026-02-12 16:27:07 +01:00
committed by GitHub
parent 029a8fbaa6
commit f66ceffd75
658 changed files with 168038 additions and 718825 deletions
@@ -393,7 +393,7 @@ namespace Opc.Ua.Client.ComplexTypes
var dataTypeNodeId = ExpandedNodeId.ToNodeId(
dataTypeId,
m_complexTypeResolver.NamespaceUris);
if (!NodeId.IsNull(dataTypeNodeId))
if (!dataTypeNodeId.IsNull)
{
CollectAllDataTypeDefinitions(dataTypeNodeId, dataTypeDefinitions);
}
@@ -404,7 +404,7 @@ namespace Opc.Ua.Client.ComplexTypes
NodeId nodeId,
NodeIdDictionary<DataTypeDefinition> collect)
{
if (NodeId.IsNull(nodeId))
if (nodeId.IsNull)
{
return;
}
@@ -538,7 +538,7 @@ namespace Opc.Ua.Client.ComplexTypes
NodeId nodeId = dictionary.DataTypes
.FirstOrDefault(d => d.Value.Name == item.Name)
.Key;
if (nodeId == null)
if (nodeId.IsNull)
{
m_logger.LogError(
Utils.TraceMasks.Error,
@@ -1001,12 +1001,13 @@ namespace Opc.Ua.Client.ComplexTypes
/// </summary>
private static StructureDefinition GetStructureDefinition(DataTypeNode dataTypeNode)
{
if (dataTypeNode.DataTypeDefinition?.Body is StructureDefinition structureDefinition)
if (dataTypeNode.DataTypeDefinition.TryGetEncodeable(
out StructureDefinition structureDefinition))
{
// Validate the DataTypeDefinition structure,
// but not if the type is supported
if (structureDefinition.Fields == null ||
structureDefinition.BaseDataType.IsNullNodeId ||
structureDefinition.BaseDataType.IsNull ||
structureDefinition.BinaryEncodingId.IsNull)
{
return null;
@@ -1017,7 +1018,7 @@ namespace Opc.Ua.Client.ComplexTypes
// validate if the DataTypeDefinition is correctly
// filled out, some servers don't do it yet...
if (field.BinaryEncodingId.IsNull ||
field.DataType.IsNullNodeId ||
field.DataType.IsNull ||
field.TypeId.IsNull ||
field.Name == null)
{
@@ -1063,7 +1064,7 @@ namespace Opc.Ua.Client.ComplexTypes
{
superType = await m_complexTypeResolver.FindSuperTypeAsync(superType, ct)
.ConfigureAwait(false);
if (superType.IsNullNodeId)
if (superType.IsNull)
{
throw new ServiceResultException(
StatusCodes.BadNodeIdInvalid,
@@ -1144,7 +1145,7 @@ namespace Opc.Ua.Client.ComplexTypes
m_dataTypeDefinitionCache[enumType.NodeId] = enumDefinition;
newType = complexTypeBuilder.AddEnumType(
enumeratedObject.Name,
QualifiedName.From(enumeratedObject.Name),
enumDefinition);
}
if (newType == null)
@@ -1187,7 +1188,7 @@ namespace Opc.Ua.Client.ComplexTypes
/// </summary>
private void AddEncodeableType(ExpandedNodeId nodeId, Type type)
{
if (NodeId.IsNull(nodeId) || type == null)
if (nodeId.IsNull || type == null)
{
return;
}
@@ -1211,7 +1212,8 @@ namespace Opc.Ua.Client.ComplexTypes
// 1. use DataTypeDefinition
if (DisableDataTypeDefinition ||
enumTypeNode.DataTypeDefinition?.Body is not EnumDefinition enumDefinition)
!enumTypeNode.DataTypeDefinition.TryGetEncodeable(
out EnumDefinition enumDefinition))
{
// browse for EnumFields or EnumStrings property
object enumTypeArray = await m_complexTypeResolver
@@ -1392,10 +1394,12 @@ namespace Opc.Ua.Client.ComplexTypes
field.IsOptional,
ct)
.ConfigureAwait(false);
if (superType?.IsNullNodeId == false)
if (!superType.IsNull)
{
field.DataType = superType;
#pragma warning disable EPC30 // Method calls itself recursively
return await GetFieldTypeAsync(field, allowSubTypes, ct).ConfigureAwait(false);
#pragma warning restore EPC30 // Method calls itself recursively
}
return null;
}
@@ -1430,7 +1434,7 @@ namespace Opc.Ua.Client.ComplexTypes
{
superType = await m_complexTypeResolver.FindSuperTypeAsync(superType, ct)
.ConfigureAwait(false);
if (superType?.IsNullNodeId != false)
if (superType.IsNull)
{
return default;
}
@@ -1465,9 +1469,9 @@ namespace Opc.Ua.Client.ComplexTypes
return default;
}
// end search if a valid BuiltInType is found. Treat type as opaque.
else if (superType.IdType == IdType.Numeric &&
(uint)superType.Identifier >= (uint)BuiltInType.Boolean &&
(uint)superType.Identifier <= (uint)BuiltInType.DiagnosticInfo)
else if (superType.TryGetIdentifier(out uint id) &&
id >= (uint)BuiltInType.Boolean &&
id <= (uint)BuiltInType.DiagnosticInfo)
{
return superType;
}