private void WriteOptionalProperty(IndentedTextWriter writer, ClassDefinition.Property p, int index, bool parentHasOptionalFields) { WritePropertyDocumentation(writer, p, isUnion: false); var type = RenderType(p, isOptional: true); var field = GetFieldName(p.SymbolicName); writer.WriteLine($"public {type} {p.SymbolicName}"); writer.Begin("{"); writer.WriteLine($"get => {field};"); writer.WriteLine("set"); writer.Begin("{"); if (parentHasOptionalFields) { writer.WriteLine($"uint flag = 1u << ({index} + base.OptionalFieldCount);"); } else { writer.WriteLine($"uint flag = 1u << {index};"); } writer.WriteLine(); writer.WriteLine($"{field} = value;"); writer.WriteLine("EncodingMask = value is null"); writer.Indent++; writer.WriteLine("? EncodingMask & ~flag"); writer.WriteLine(": EncodingMask | flag;"); writer.Indent--; writer.End("}"); writer.End("}"); writer.WriteLine($"private {type} {field};"); }
/* * Enumeration */ private void WriteEnumeration(IndentedTextWriter writer, EnumDefinition e) { WriteDocumentation(writer, e); if (_typeSet.TryGetExpandedNodeId(e.DataTypeId, out var eId)) { var idString = ToStringLiteral(eId.ToString()); writer.WriteLine($"[Workstation.ServiceModel.Ua.DataTypeId({idString})]"); } else { throw new InvalidDataException($"No data type id for enum {e.SymbolicName}."); } writer.WriteLine($"public enum {e.SymbolicName}"); writer.Begin("{"); foreach (var item in e.Items) { if (item.Description != null) { writer.WriteLine("/// <summary>"); foreach (var line in item.Description.WordWrap(76 - 4 * writer.Indent)) { writer.WriteLine($"/// {line}"); } writer.WriteLine("/// </summary>"); } writer.WriteLine($"{item.SymbolicName} = {item.Value},"); } writer.End("}"); }
/* * Union */ private void WriteUnion(IndentedTextWriter writer, ClassDefinition c, string name, IEnumerable <NestedType> nestedTypes) { WriteDocumentation(writer, c, isUnion: true); WriteAttributes(writer, c); WriteUnionHeader(writer, c, name); writer.Begin("{"); if (nestedTypes.Any()) { WriteNestedTypes(writer, nestedTypes); } WriteUnionEnum(writer, c); writer.WriteLine(); WriteUnionFields(writer); writer.WriteLine(); foreach (var p in c.Properties) { WriteUnionProperty(writer, p); writer.WriteLine(); } WriteUnionEncodeMethod(writer, c); writer.WriteLine(); WriteUnionDecodeMethod(writer, c); writer.End("}"); }
/* * Static class */ private void WriteStaticClass(IndentedTextWriter writer, string name, IEnumerable <NestedType> nestedTypes) { writer.WriteLine($"public static class {name}"); writer.Begin("{"); WriteNestedTypes(writer, nestedTypes); writer.End("}"); }
private void WriteEncodeMethod(IndentedTextWriter writer, ClassDefinition c, bool isDerived, bool parentIsStructure, bool parentHasOptionalFields) { var hasOptionalFields = c.OptionalPropertyCount != 0; var modifier = isDerived ? "override" : "virtual"; WriteInheritDoc(writer); writer.WriteLine($"public {modifier} void Encode(Workstation.ServiceModel.Ua.IEncoder encoder)"); writer.Begin("{"); if (isDerived && !parentIsStructure) { writer.WriteLine("base.Encode(encoder);"); } writer.WriteLine($"encoder.PushNamespace({ToStringLiteral(c.Namespace)});"); writer.WriteLine(); if (hasOptionalFields && !parentHasOptionalFields) { writer.WriteLine("encoder.WriteUInt32(\"EncodingMask\", EncodingMask);"); } var index = 0; foreach (var p in c.Properties) { var netType = _typeSet.GetNetType(p.DataTypeId); var suffix = RenderMethodSuffix(netType, p.Rank); if (p.IsOptional) { writer.WriteLine($"if ({p.SymbolicName} is {{}} opt{index})"); writer.Begin("{"); writer.WriteLine($"encoder.Write{suffix}({ToStringLiteral(p.OpcUaName)}, opt{index});"); writer.End("}"); index++; } else { writer.WriteLine($"encoder.Write{suffix}({ToStringLiteral(p.OpcUaName)}, {p.SymbolicName});"); } } writer.WriteLine(); writer.WriteLine("encoder.PopNamespace();"); writer.End("}"); }
private void WriteUnionProperty(IndentedTextWriter writer, ClassDefinition.Property p) { WritePropertyDocumentation(writer, p, isUnion: true); var netType = _typeSet.GetNetType(p.DataTypeId); var r = p.Rank switch { 2 => "[,]", 1 => "[]", _ => "" }; var type = $"{netType.TypeName}{r}"; writer.WriteLine($"public {type} {p.SymbolicName}"); writer.Begin("{"); writer.WriteLine($"get => ({type})_field;"); writer.WriteLine("set"); writer.Begin("{"); writer.WriteLine($"SwitchField = UnionField.{p.SymbolicName};"); writer.WriteLine($"_field = value;"); writer.End("}"); writer.End("}"); }
/* * Class and unions */ private void WriteClass(IndentedTextWriter writer, ClassDefinition c, string name, IEnumerable <NestedType> nestedTypes) { bool isDerived = c.ParentDataTypeId != null; bool parentIsStructure = c.ParentDataTypeId == NodeId.Parse(DataTypeIds.Structure); WriteDocumentation(writer, c, isUnion: false); WriteAttributes(writer, c); var hasOptionalFields = c.OptionalPropertyCount != 0; var parentHasOptionalFields = _typeSet.ParentHasOptionalProperties(c); WriteClassHeader(writer, c, name, parentHasOptionalFields); writer.Begin("{"); if (nestedTypes.Any()) { WriteNestedTypes(writer, nestedTypes); } if (hasOptionalFields) { WriteOptionalFieldsImplementation(writer, c, parentHasOptionalFields); } var optional = 0; foreach (var p in c.Properties) { if (p.IsOptional) { WriteOptionalProperty(writer, p, optional, parentHasOptionalFields); optional++; } else { WriteProperty(writer, p); } writer.WriteLine(); } bool hasParentMethods = isDerived && !parentIsStructure; if (c.Properties.Any() || !hasParentMethods) { WriteEncodeMethod(writer, c, isDerived, parentIsStructure, parentHasOptionalFields); writer.WriteLine(); WriteDecodeMethod(writer, c, isDerived, parentIsStructure, parentHasOptionalFields); } writer.End("}"); }
private void WriteUnionEnum(IndentedTextWriter writer, ClassDefinition c) { writer.WriteLine("public enum UnionField"); writer.Begin("{"); writer.WriteLine("Null = 0,"); var i = 1; foreach (var p in c.Properties) { writer.WriteLine($"{p.SymbolicName} = {i},"); i++; } writer.End("}"); }
public void Write(IndentedTextWriter writer) { WriteFileHeader(writer); writer.WriteLine("[assembly: Workstation.ServiceModel.Ua.TypeLibrary]"); writer.WriteLine($"namespace {_netNamespace}"); writer.Begin("{"); WriteCommonTypes(writer); WriteDefinitions(writer); writer.End("}"); }
private void WriteUnionDecodeMethod(IndentedTextWriter writer, ClassDefinition c) { WriteInheritDoc(writer); writer.WriteLine($"public override void Decode(Workstation.ServiceModel.Ua.IDecoder decoder)"); writer.Begin("{"); writer.WriteLine($"decoder.PushNamespace({ToStringLiteral(c.Namespace)});"); writer.WriteLine(); writer.WriteLine($"var switchField = (UnionField)decoder.ReadUInt32(null);"); writer.WriteLine($"switch (switchField)"); writer.Begin("{"); writer.WriteLine("case UnionField.Null:"); writer.Indent++; writer.WriteLine("_field = null;"); writer.WriteLine("break;"); writer.Indent--; foreach (var p in c.Properties) { var netType = _typeSet.GetNetType(p.DataTypeId); var suffix = RenderMethodSuffix(netType, p.Rank); writer.WriteLine($"case UnionField.{p.SymbolicName}:"); writer.Indent++; writer.WriteLine($"{p.SymbolicName} = decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)});"); writer.WriteLine("break;"); writer.Indent--; } writer.WriteLine("default:"); writer.Indent++; writer.WriteLine("throw new Workstation.ServiceModel.Ua.ServiceResultException(Workstation.ServiceModel.Ua.StatusCodes.BadEncodingError);"); writer.Indent--; writer.End("}"); writer.WriteLine("decoder.PopNamespace();"); writer.End("}"); }
private void WriteDecodeMethod(IndentedTextWriter writer, ClassDefinition c, bool isDerived, bool parentIsStructure, bool parentHasOptionalFields) { var hasOptionalFields = c.OptionalPropertyCount != 0; var modifier = isDerived ? "override" : "virtual"; WriteInheritDoc(writer); writer.WriteLine($"public {modifier} void Decode(Workstation.ServiceModel.Ua.IDecoder decoder)"); writer.Begin("{"); if (hasOptionalFields && parentHasOptionalFields) { writer.WriteLine("int offset = base.OptionalFieldCount;"); writer.WriteLine(); } if (isDerived && !parentIsStructure) { writer.WriteLine("base.Decode(decoder);"); } writer.WriteLine($"decoder.PushNamespace({ToStringLiteral(c.Namespace)});"); writer.WriteLine(); if (hasOptionalFields) { if (!parentHasOptionalFields) { writer.WriteLine("var encodingMask = decoder.ReadUInt32(null);"); writer.WriteLine("EncodingMask = encodingMask;"); } else { writer.WriteLine("var encodingMask = EncodingMask;"); } writer.WriteLine(); } var index = 0; foreach (var p in c.Properties) { var netType = _typeSet.GetNetType(p.DataTypeId); var suffix = RenderMethodSuffix(netType, p.Rank); var type = RenderType(p, isOptional: true); if (p.IsOptional) { if (parentHasOptionalFields) { writer.WriteLine($"{p.SymbolicName} = (encodingMask & (1u << ({index} + offset))) != 0"); } else { writer.WriteLine($"{p.SymbolicName} = (encodingMask & (1u << {index})) != 0"); } writer.Indent++; writer.WriteLine($"? decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)})"); writer.WriteLine($": default({type});"); writer.Indent--; index++; } else { writer.WriteLine($"{p.SymbolicName} = decoder.Read{suffix}({ToStringLiteral(p.OpcUaName)});"); } } writer.WriteLine(); writer.WriteLine("decoder.PopNamespace();"); writer.End("}"); }