/// <summary> /// Generates the tags enumeration for a choice /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="def">The choice definition</param> private void _generateChoiceTags(CSharpEmitter emitter, ChoiceDefinition def) { emitter.WriteLine(); using (var tagEmitter = emitter.Enum("Tags", "byte")) { for (int i = 0; i < def.Fields.Length; i++) { var field = def.Fields[i]; var fieldName2 = _transformFieldName(field.Name); tagEmitter.EnumValue(fieldName2, i, i == def.Fields.Length - 1); } } }
/// <summary> /// Generates code for a named type /// </summary> /// <param name="type">The type to generate for</param> public void Generate(NamedType type) { string name = _transformTypeName(type.Name); string path = Path.Combine(_directory, name + ".cs"); using(var emitter = new CSharpEmitter(path)) { emitter.EmitUsing("System"); emitter.EmitUsing("BACnet.Types"); emitter.EmitUsing("BACnet.Types.Schemas"); emitter.WriteLine(); using(var ns = emitter.Namespace(_namespace)) { _generateDefinition(ns, name, null, type.Definition, true, null); } } }
/// <summary> /// If necessary, generates a wrapper for each non-sequence, non-choice option /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="choiceName">The name of the choice type</param> /// <param name="def">The choice definition</param> private void _generateChoiceOptionWrappers(CSharpEmitter emitter, string choiceName, ChoiceDefinition def) { foreach (var field in def.Fields) { bool needsWrapper = def.Fields.Any(f => _choiceOptionNeedsWrapper(f)); var fieldName = _transformFieldName(field.Name); var typeName = _getDefinitionName(null, fieldName, field.Type); if (needsWrapper) { emitter.WriteLine(); using (var wrapper = _generateWrapperType(emitter, fieldName + "Wrapper", typeName, choiceName, fieldName)) { } } } }
/// <summary> /// Generates code for a named type /// </summary> /// <param name="type">The type to generate for</param> public void Generate(NamedType type) { string name = _transformTypeName(type.Name); string path = Path.Combine(_directory, name + ".cs"); using (var emitter = new CSharpEmitter(path)) { emitter.EmitUsing("System"); emitter.EmitUsing("BACnet.Types"); emitter.EmitUsing("BACnet.Types.Schemas"); emitter.WriteLine(); using (var ns = emitter.Namespace(_namespace)) { _generateDefinition(ns, name, null, type.Definition, true, null); } } }
/// <summary> /// If necessary, generates a wrapper for each non-sequence, non-choice option /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="choiceName">The name of the choice type</param> /// <param name="def">The choice definition</param> private void _generateChoiceOptionWrappers(CSharpEmitter emitter, string choiceName, ChoiceDefinition def) { foreach(var field in def.Fields) { bool needsWrapper = def.Fields.Any(f => _choiceOptionNeedsWrapper(f)); var fieldName = _transformFieldName(field.Name); var typeName = _getDefinitionName(null, fieldName, field.Type); if (needsWrapper) { emitter.WriteLine(); using (var wrapper = _generateWrapperType(emitter, fieldName + "Wrapper", typeName, choiceName, fieldName)) { } } } }
/// <summary> /// Generates a choice type /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="typeName">The name of the type</param> /// <param name="def">The choice definition</param> private void _generateChoice(CSharpEmitter emitter, string typeName, string fieldName, ChoiceDefinition def, bool root = false) { typeName = _getDefinitionName(typeName, fieldName, def); if (!root) { _generateChoiceTags(emitter, def); emitter.WriteLine(); } using(var cls = emitter.Class(typeName, true)) { cls.AbstractProperty("Tag", "Tags", Access.Public); foreach(var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); var valueTypeName = _getDefinitionName(null, field.Name, field.Type); cls.WriteLine(); cls.Property("Is" + tag, "bool", "return this.Tag == Tags." + tag + ";"); cls.WriteLine(); cls.Property("As" + tag, valueTypeName, _choiceOptionNeedsWrapper(field) ? "return ((" + optionTypeName + ")this).Item;" : "return (" + optionTypeName + ")this;"); cls.WriteLine(); Parameter[] parameters = _getChoiceOptionForwardedParameters(field); using(var method = cls.StaticMethod("New" + tag, typeName, parameters)) { var paramsArr = parameters.Select(p => p.Name).ToArray(); var paramsStr = string.Join(", ", paramsArr); method.WriteLine("return new " + optionTypeName + "(" + paramsStr + ");"); } } cls.WriteLine(); var schemaStr = "new ChoiceSchema(false, " + Environment.NewLine + string.Join("," + Environment.NewLine, def.Fields.Select(f => cls.IndentString(1) + "new FieldSchema(\"" + _transformFieldName(f.Name) + "\", " + f.Tag + ", Value<" + _getDefinitionName(null, f.Name, f.Type) + ">.Schema)").ToArray()) + ")"; cls.StaticReadonlyField("Schema", "ISchema", schemaStr); cls.WriteLine(); using (var load = cls.StaticMethod("Load", typeName, new Parameter[] { new Parameter("IValueStream", "stream") })) { load.WriteLine("{0} ret = null;", typeName); load.WriteLine("Tags tag = (Tags)stream.EnterChoice();"); using (var sw = load.Switch("tag")) { foreach(var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); sw.Case("Tags." + tag); sw.WriteLine("ret = Value<{0}>.Load(stream);", optionTypeName); sw.Break(); } sw.Default(); sw.WriteLine("throw new Exception();"); sw.Indent--; } load.WriteLine("stream.LeaveChoice();"); load.WriteLine("return ret;"); } cls.WriteLine(); using (var save = cls.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(typeName, "value") })) { save.WriteLine("sink.EnterChoice((byte)value.Tag);"); using (var sw = save.Switch("value.Tag")) { foreach(var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); sw.Case("Tags." + tag); sw.WriteLine("Value<{0}>.Save(sink, ({0})value);", optionTypeName); sw.Break(); } sw.Default(); sw.WriteLine("throw new Exception();"); sw.Indent--; } save.WriteLine("sink.LeaveChoice();"); } if (root) { _generateChoiceTags(cls, def); _generateChoiceOptions(cls, typeName, def); } } if (!root) { _generateChoiceOptions(emitter, typeName, def); } }
/// <summary> /// Generates a choice type /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="typeName">The name of the type</param> /// <param name="def">The choice definition</param> private void _generateChoice(CSharpEmitter emitter, string typeName, string fieldName, ChoiceDefinition def, bool root = false) { typeName = _getDefinitionName(typeName, fieldName, def); if (!root) { _generateChoiceTags(emitter, def); emitter.WriteLine(); } using (var cls = emitter.Class(typeName, true)) { cls.AbstractProperty("Tag", "Tags", Access.Public); foreach (var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); var valueTypeName = _getDefinitionName(null, field.Name, field.Type); cls.WriteLine(); cls.Property("Is" + tag, "bool", "return this.Tag == Tags." + tag + ";"); cls.WriteLine(); cls.Property("As" + tag, valueTypeName, _choiceOptionNeedsWrapper(field) ? "return ((" + optionTypeName + ")this).Item;" : "return (" + optionTypeName + ")this;"); cls.WriteLine(); Parameter[] parameters = _getChoiceOptionForwardedParameters(field); using (var method = cls.StaticMethod("New" + tag, typeName, parameters)) { var paramsArr = parameters.Select(p => p.Name).ToArray(); var paramsStr = string.Join(", ", paramsArr); method.WriteLine("return new " + optionTypeName + "(" + paramsStr + ");"); } } cls.WriteLine(); var schemaStr = "new ChoiceSchema(false, " + Environment.NewLine + string.Join("," + Environment.NewLine, def.Fields.Select(f => cls.IndentString(1) + "new FieldSchema(\"" + _transformFieldName(f.Name) + "\", " + f.Tag + ", Value<" + _getDefinitionName(null, f.Name, f.Type) + ">.Schema)").ToArray()) + ")"; cls.StaticReadonlyField("Schema", "ISchema", schemaStr); cls.WriteLine(); using (var load = cls.StaticMethod("Load", typeName, new Parameter[] { new Parameter("IValueStream", "stream") })) { load.WriteLine("{0} ret = null;", typeName); load.WriteLine("Tags tag = (Tags)stream.EnterChoice();"); using (var sw = load.Switch("tag")) { foreach (var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); sw.Case("Tags." + tag); sw.WriteLine("ret = Value<{0}>.Load(stream);", optionTypeName); sw.Break(); } sw.Default(); sw.WriteLine("throw new Exception();"); sw.Indent--; } load.WriteLine("stream.LeaveChoice();"); load.WriteLine("return ret;"); } cls.WriteLine(); using (var save = cls.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(typeName, "value") })) { save.WriteLine("sink.EnterChoice((byte)value.Tag);"); using (var sw = save.Switch("value.Tag")) { foreach (var field in def.Fields) { var tag = _transformFieldName(field.Name); var optionTypeName = _choiceOptionNeedsWrapper(field) ? _transformFieldName(field.Name) + "Wrapper" : _getDefinitionName(null, field.Name, field.Type); sw.Case("Tags." + tag); sw.WriteLine("Value<{0}>.Save(sink, ({0})value);", optionTypeName); sw.Break(); } sw.Default(); sw.WriteLine("throw new Exception();"); sw.Indent--; } save.WriteLine("sink.LeaveChoice();"); } if (root) { _generateChoiceTags(cls, def); _generateChoiceOptions(cls, typeName, def); } } if (!root) { _generateChoiceOptions(emitter, typeName, def); } }