/// <summary> /// Generates a wrapper type /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="name">The name of the wrapper type</param> /// <param name="wrappedType">The name of the type to wrap</param> /// <returns>The emitter for the type body</returns> private CSharpEmitter _generateWrapperType(CSharpEmitter emitter, string name, string wrappedType, string choiceBase = null, string tag = null) { var typeEmitter = choiceBase == null?emitter.Class(name) : emitter.Class(name, false, new string[] { choiceBase });; if (tag != null) { typeEmitter.OverrideProperty("Tag", "Tags", "return Tags." + tag + ";"); typeEmitter.WriteLine(); } typeEmitter.Property("Item", wrappedType, Access.Public); typeEmitter.WriteLine(); using (var cons = typeEmitter.Constructor(name, new Parameter[] { new Parameter(wrappedType, "item") })) { cons.WriteLine("this.Item = item;"); } typeEmitter.WriteLine(); typeEmitter.StaticReadonlyField("Schema", "ISchema", "Value<" + wrappedType + ">.Schema", @new: !string.IsNullOrEmpty(choiceBase)); typeEmitter.WriteLine(); using (var load = typeEmitter.StaticMethod("Load", name, new Parameter[] { new Parameter("IValueStream", "stream") }, @new: !string.IsNullOrEmpty(choiceBase))) { load.WriteLine("var temp = Value<" + wrappedType + ">.Load(stream);"); load.WriteLine("return new " + name + "(temp);"); } typeEmitter.WriteLine(); using (var save = typeEmitter.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(name, "value") })) { save.WriteLine("Value<" + wrappedType + ">.Save(sink, value.Item);"); } typeEmitter.WriteLine(); return(typeEmitter); }
/// <summary> /// Generates a wrapper type /// </summary> /// <param name="emitter">The emitter to write to</param> /// <param name="name">The name of the wrapper type</param> /// <param name="wrappedType">The name of the type to wrap</param> /// <returns>The emitter for the type body</returns> private CSharpEmitter _generateWrapperType(CSharpEmitter emitter, string name, string wrappedType, string choiceBase = null, string tag = null) { var typeEmitter = choiceBase == null ? emitter.Class(name) : emitter.Class(name, false, new string[] { choiceBase });; if(tag != null) { typeEmitter.OverrideProperty("Tag", "Tags", "return Tags." + tag + ";"); typeEmitter.WriteLine(); } typeEmitter.Property("Item", wrappedType, Access.Public); typeEmitter.WriteLine(); using (var cons = typeEmitter.Constructor(name, new Parameter[] { new Parameter(wrappedType, "item") })) { cons.WriteLine("this.Item = item;"); } typeEmitter.WriteLine(); typeEmitter.StaticReadonlyField("Schema", "ISchema", "Value<" + wrappedType + ">.Schema", @new:!string.IsNullOrEmpty(choiceBase)); typeEmitter.WriteLine(); using (var load = typeEmitter.StaticMethod("Load", name, new Parameter[] { new Parameter("IValueStream", "stream") }, @new: !string.IsNullOrEmpty(choiceBase))) { load.WriteLine("var temp = Value<" + wrappedType + ">.Load(stream);"); load.WriteLine("return new " + name + "(temp);"); } typeEmitter.WriteLine(); using (var save = typeEmitter.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(name, "value") })) { save.WriteLine("Value<" + wrappedType + ">.Save(sink, value.Item);"); } typeEmitter.WriteLine(); return typeEmitter; }
/// <summary> /// Generates a sequence type /// </summary> /// <param name="typeName">The name of the type</param> /// <param name="def">The sequence definition</param> private void _generateSequence(CSharpEmitter emitter, string typeName, string fieldName, SequenceDefinition def, bool root = false, string tag = null, string choiceBase = null) { string[] bases = choiceBase == null ? new string[0] { } : new string[] { choiceBase }; typeName = _getDefinitionName(typeName, fieldName, def); using(var cls = emitter.Class(typeName, false, bases)) { if(tag != null) { cls.OverrideProperty("Tag", "Tags", "return Tags." + tag + ";"); cls.WriteLine(); } foreach (var field in def.Fields) { var fieldName2 = _transformFieldName(field.Name); var typeName2 = _sequenceFieldTypeName(field); cls.Property(fieldName2, typeName2); cls.WriteLine(); } var cparams = def.Fields.Select(f => new Parameter( _sequenceFieldTypeName(f), _fieldNameToTempName(f.Name))) .ToArray(); using (var cons = cls.Constructor(typeName, cparams, Access.Public)) { foreach (var field in def.Fields) { cons.WriteLine("this.{0} = {1};", _transformFieldName(field.Name), _fieldNameToTempName(field.Name)); } } cls.WriteLine(); var schemaStr = "new SequenceSchema(false, " + Environment.NewLine + string.Join("," + Environment.NewLine, def.Fields.Select(f => cls.IndentString(1) + "new FieldSchema(\"" + _transformFieldName(f.Name) + "\", " + f.Tag + ", Value<" + _sequenceFieldTypeName(f) + ">.Schema)").ToArray()) + ")"; cls.StaticReadonlyField("Schema", "ISchema", schemaStr, @new:!string.IsNullOrEmpty(choiceBase)); cls.WriteLine(); using (var load = cls.StaticMethod("Load", typeName, new Parameter[] { new Parameter("IValueStream", "stream") }, @new:!string.IsNullOrEmpty(choiceBase))) { load.WriteLine("stream.EnterSequence();"); foreach(var field in def.Fields) { load.WriteLine("var {0} = Value<{1}>.Load(stream);", _fieldNameToTempName(field.Name), _sequenceFieldTypeName(field)); } load.WriteLine("stream.LeaveSequence();"); load.WriteLine("return new " + typeName + "(" + string.Join(", ", def.Fields.Select(f => _fieldNameToTempName(f.Name)).ToArray()) + ");"); } cls.WriteLine(); using (var save = cls.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(typeName, "value") })) { save.WriteLine("sink.EnterSequence();"); foreach (var field in def.Fields) { save.WriteLine("Value<{0}>.Save(sink, value.{1});", _sequenceFieldTypeName(field), _transformFieldName(field.Name)); } save.WriteLine("sink.LeaveSequence();"); } if (root) _generateSequenceFields(cls, def); } if (!root) _generateSequenceFields(emitter, 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); } }
/// <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 sequence type /// </summary> /// <param name="typeName">The name of the type</param> /// <param name="def">The sequence definition</param> private void _generateSequence(CSharpEmitter emitter, string typeName, string fieldName, SequenceDefinition def, bool root = false, string tag = null, string choiceBase = null) { string[] bases = choiceBase == null ? new string[0] { } : new string[] { choiceBase }; typeName = _getDefinitionName(typeName, fieldName, def); using (var cls = emitter.Class(typeName, false, bases)) { if (tag != null) { cls.OverrideProperty("Tag", "Tags", "return Tags." + tag + ";"); cls.WriteLine(); } foreach (var field in def.Fields) { var fieldName2 = _transformFieldName(field.Name); var typeName2 = _sequenceFieldTypeName(field); cls.Property(fieldName2, typeName2); cls.WriteLine(); } var cparams = def.Fields.Select(f => new Parameter( _sequenceFieldTypeName(f), _fieldNameToTempName(f.Name))) .ToArray(); using (var cons = cls.Constructor(typeName, cparams, Access.Public)) { foreach (var field in def.Fields) { cons.WriteLine("this.{0} = {1};", _transformFieldName(field.Name), _fieldNameToTempName(field.Name)); } } cls.WriteLine(); var schemaStr = "new SequenceSchema(false, " + Environment.NewLine + string.Join("," + Environment.NewLine, def.Fields.Select(f => cls.IndentString(1) + "new FieldSchema(\"" + _transformFieldName(f.Name) + "\", " + f.Tag + ", Value<" + _sequenceFieldTypeName(f) + ">.Schema)").ToArray()) + ")"; cls.StaticReadonlyField("Schema", "ISchema", schemaStr, @new: !string.IsNullOrEmpty(choiceBase)); cls.WriteLine(); using (var load = cls.StaticMethod("Load", typeName, new Parameter[] { new Parameter("IValueStream", "stream") }, @new: !string.IsNullOrEmpty(choiceBase))) { load.WriteLine("stream.EnterSequence();"); foreach (var field in def.Fields) { load.WriteLine("var {0} = Value<{1}>.Load(stream);", _fieldNameToTempName(field.Name), _sequenceFieldTypeName(field)); } load.WriteLine("stream.LeaveSequence();"); load.WriteLine("return new " + typeName + "(" + string.Join(", ", def.Fields.Select(f => _fieldNameToTempName(f.Name)).ToArray()) + ");"); } cls.WriteLine(); using (var save = cls.StaticMethod("Save", "void", new Parameter[] { new Parameter("IValueSink", "sink"), new Parameter(typeName, "value") })) { save.WriteLine("sink.EnterSequence();"); foreach (var field in def.Fields) { save.WriteLine("Value<{0}>.Save(sink, value.{1});", _sequenceFieldTypeName(field), _transformFieldName(field.Name)); } save.WriteLine("sink.LeaveSequence();"); } if (root) { _generateSequenceFields(cls, def); } } if (!root) { _generateSequenceFields(emitter, def); } }