public virtual CodeWriter WriteNestedTypes(Schema.Node node, Stack <UnionStub> union) { var children = node.nestedNodes; var seen = new HashSet <ulong>(); if (children.IsValid()) { foreach (var child in children) { if (seen.Add(child.id)) { var found = Lookup(child.id); if (found.IsValid()) { WriteNode(found, union); } else { WriteWarning("not found: " + child.id + " / " + child.name); } } } } return(this); }
public virtual CodeWriter WriteNode(Schema.Node node, Stack <UnionStub> union) { if (node.IsValid()) { switch (node.Union) { case Schema.Node.Unions.@struct: WriteStruct(node, union); break; case Schema.Node.Unions.@enum: WriteEnum(node); break; case Schema.Node.Unions.@const: WriteConst(node); break; case Schema.Node.Unions.annotation: default: WriteLine().WriteComment(string.Format("Not implemented: {0} ({1}))", node.displayName, node.Union)); break; } } return(this); }
protected Schema.Node FindParent(Schema.Node node) { if (!node.IsValid() || node.id == 0) { return(default(Node)); } if (node.scopeId != 0 && node.scopeId != node.id) { var tmp = Lookup(node.scopeId); if (tmp.IsValid()) { return(tmp); } } foreach (var pair in map) { var nested = pair.Value.nestedNodes; if (nested.IsValid()) { foreach (var x in nested) { if (x.id == node.id) { return(pair.Value); } } } } return(default(Node)); }
public override CodeWriter WriteCustomSerializerClass(Schema.Node node, string typeName, string methodName) { throw new NotSupportedException(); //WriteLine().Write("class ").Write(typeName).Write(" : global::").Write(Namespace).Write(".").Write(Escape(Serializer)) // .Write(".").Write(Schema.CodeGeneratorRequest.BaseTypeName).Write(", global::CapnProto.ITypeSerializer<").Write(FullyQualifiedName(node)).Write(">"); //Indent(); //WriteLine().Write("private readonly ").Write(typeof(TypeModel)).Write(" model;"); //WriteLine().Write("internal ").Write(typeName).Write("(").Write(typeof(TypeModel)).Write(" model)"); //Indent(); //WriteLine().Write("this.model = model;"); //Outdent(); //WriteLine().Write(typeof(TypeModel)).Write(" ").Write(typeof(ITypeSerializer)).Write(".Model { get { return this.model; } }"); //WriteLine().Write("object ").Write(typeof(ITypeSerializer)).Write(".Deserialize(int segment, int origin, ").Write(typeof(DeserializationContext)).Write(" ctx, ulong pointer)"); //Indent().WriteLine().Write("return ").Write(methodName).Write("(segment, origin, ctx, pointer);"); //EndMethod(); //WriteLine().Write("public ").Write(FullyQualifiedName(node)).Write(" Deserialize(int segment, int origin, ").Write(typeof(DeserializationContext)).Write(" ctx, ulong pointer)"); //Indent().WriteLine().Write("return ").Write(methodName).Write("(segment, origin, ctx, pointer);"); //EndMethod(); //return EndClass(); }
private string FullyQualifiedName(Schema.Node node) { var parent = FindParent(node); Stack <Schema.Node> roots = null; if (((Pointer)parent).IsValid && parent.Union != Node.Unions.file) { roots = new Stack <Schema.Node>(); do { roots.Push(parent); parent = FindParent(parent); } while (((Pointer)parent).IsValid && parent.Union != Node.Unions.file); } var sb = new StringBuilder("global::"); if (!string.IsNullOrWhiteSpace(Namespace)) { sb.Append(Namespace).Append('.'); } while (roots != null && roots.Count != 0) { parent = roots.Pop(); sb.Append(LocalName(parent)).Append('.'); } return(sb.Append(LocalName(node)).ToString()); }
public override CodeWriter WriteGroupAccessor(Schema.Node parent, Schema.Node child, string name, bool extraNullable) { BeginProperty(child, name, extraNullable); WriteLine().Write("get"); Indent(); WriteLine().Write("return new ").Write(FullyQualifiedName(child)).Write("(this.").Write(PointerName).Write(");"); Outdent(); return(Outdent()); }
public override CodeWriter WriteConst(Schema.Node node) { if (!node.IsValid() || node.Union != Schema.Node.Unions.@const) { return(this); } var @const = node.@const; return(WriteLine().Write("public const ").Write(@const.type).Write(" ").Write(LocalName(node)).Write(" = ").Write(@const.type, @const.value).Write(";")); }
public override CodeWriter BeginClass(Schema.Node node) { if (node.Union == Schema.Node.Unions.@struct) { var @struct = node.@struct; if (@struct.isGroup) { WriteLine().Write("[").Write(typeof(GroupAttribute)).Write("]"); } else { WriteLine().Write("[").Write(typeof(StructAttribute)).Write("(").Write(typeof(ElementSize)).Write(".") .Write(((ElementSize)@struct.preferredListEncoding).ToString()).Write(", ") .Write(@struct.dataWordCount).Write(", ").Write(@struct.pointerCount).Write(")]"); } if (node.id != 0) { WriteLine().Write("[").Write(typeof(IdAttribute)).Write("(").Write(node.id).Write(")]"); } } string localName = LocalName(node), fullName = FullyQualifiedName(node); WriteLine().Write("public partial struct ").Write(localName).Write(" : ").Write(typeof(IPointer)); Indent(); WriteLine().Write("private ").Write(typeof(Pointer)).Write(" ").Write(PointerName).Write(";"); WriteLine().Write("private ").Write(localName).Write("(").Write(typeof(Pointer)).Write(" pointer){ this.").Write(PointerName).Write(" = pointer; }"); WriteLine().Write("public static explicit operator ").Write(fullName).Write("(").Write(typeof(Pointer)).Write(" pointer) { return new ").Write(fullName).Write("(pointer); }"); WriteLine().Write("public static implicit operator ").Write(typeof(Pointer)).Write(" (").Write(fullName).Write(" obj) { return obj.").Write(PointerName).Write("; }"); WriteLine().Write("public override int GetHashCode() { return this.").Write(PointerName).Write(".GetHashCode(); }"); WriteLine().Write("partial void OnToString(ref string s);"); WriteLine().Write("public override string ToString() { string s = null; this.OnToString(ref s); return s ?? this.").Write(PointerName).Write(".ToString(); }"); WriteLine().Write("public override bool Equals(object obj) { return obj is ").Write(fullName).Write(" && (this.") .Write(PointerName).Write(" == ((").Write(fullName).Write(")obj).").Write(PointerName).Write("); }"); WriteLine().Write(typeof(Pointer)).Write(" ").Write(typeof(IPointer)).Write(".Pointer { get { return this.").Write(PointerName).Write("; } }"); WriteLine().Write("public ").Write(fullName).Write(" Dereference() { return (").Write(fullName).Write(")this.").Write(PointerName).Write(".Dereference(); }"); if (node.Union == Node.Unions.@struct) { if ([email protected] != 0) { WriteLine().Write("public static ").Write(fullName).Write(" Create(").Write(typeof(Pointer)).Write(" parent, ").Write(fullName).Write(".Unions union)"); Indent(); WriteLine().Write("var ptr = parent.Allocate(").Write([email protected]).Write(", ").Write([email protected]).Write(");"); WriteLine().Write("ptr.SetUInt16(").Write([email protected]).Write(", (ushort)union);"); WriteLine().Write("return (").Write(fullName).Write(")ptr;"); Outdent(); } else { WriteLine().Write("public static ").Write(fullName).Write(" Create(").Write(typeof(Pointer)).Write(" parent) { return (").Write(fullName).Write(")parent.Allocate(") .Write([email protected]).Write(", ").Write([email protected]).Write("); }"); } } return(this); }
public override CodeWriter WriteConst(Schema.Node node) { if (!node.IsValid() || node.Union != Schema.Node.Unions.@const) { return(this); } var @const = node.@const; string localName = LocalName(node); return(WriteLine().Write("public static class C_" + localName + "{").WriteLine().Write(" public const ").Write(@const.type).Write(" ").Write(localName).Write(" = ").Write(@const.type, @const.value).Write(";").WriteLine().Write("}")); }
public override void WriteEnum(Schema.Node node) { if (!((Pointer)node).IsValid || node.Union != Schema.Node.Unions.@enum || !((Pointer)[email protected]).IsValid) { return; } WriteLine().Write("public enum ").Write(LocalName(node)); Indent(); var items = [email protected]; foreach (var item in items) { WriteLine().Write(Escape(item.name)).Write(" = ").Write(item.codeOrder).Write(","); } Outdent(); }
public override CodeWriter WriteGroup(Schema.Node node, Stack <UnionStub> union) { var parent = node; while (((Pointer)parent).IsValid && parent.IsGroup()) { parent = FindParent(parent); } if (!parent.IsValid()) { return(WriteLine().Write("#error parent not found for: ").Write(node.displayName)); } WriteLine().Write("[global::CapnProto.Group, global::CapnProto.Id(").Write(node.id).Write(")]"); WriteLine().Write("public partial struct ").Write(LocalName(node)); Indent(); WriteLine().Write("private ").Write(typeof(Pointer)).Write(" ").Write(PointerName).Write(";"); WriteLine().Write("internal ").Write(LocalName(node)).Write("(").Write(typeof(Pointer)).Write(" pointer)"); Indent(); WriteLine().Write("this.").Write(PointerName).Write(" = pointer;"); Outdent(); if ([email protected]()) { foreach (var field in [email protected](x => x.codeOrder).ThenBy(x => x.name, Text.Comparer)) { if (field.discriminantValue == Field.noDiscriminant) { WriteFieldAccessor(node, field, union); } else { union.Push(new UnionStub([email protected], field.discriminantValue)); WriteFieldAccessor(node, field, union); union.Pop(); } } } if ([email protected] != 0) { WriteDiscriminant(node, union); } WriteNestedTypes(node, union); return(Outdent()); }
private string LocalName(Schema.Node node) { string name = node.displayName.ToString(); int prefixLen = (int)node.displayNamePrefixLength; if (prefixLen != 0) { name = name.Substring(prefixLen); } if (node.IsGroup()) { return(LocalName(name + "Group")); } else { return(LocalName(name)); } }
public abstract CodeWriter WriteConst(Schema.Node node);
public abstract CodeWriter WriteCustomSerializerClass(Schema.Node node, string typeName, string methodName);
public abstract CodeWriter WriteSerializerTest(string field, Schema.Node node, string serializer);
public abstract CodeWriter WriteCustomReaderMethod(Schema.Node node);
private static void CascadePointers(CodeWriter writer, Schema.Node node, SortedList <int, List <Tuple <Schema.Node, Schema.Field, Stack <UnionStub> > > > ptrFields, Stack <UnionStub> union) { if ([email protected]()) { foreach (var field in [email protected]) { bool isFiltered = field.discriminantValue != Field.noDiscriminant; switch (field.Union) { case Field.Unions.group: { var found = writer.Lookup(field.group.typeId); if (found.IsValid()) { if (isFiltered) { union.Push(new UnionStub([email protected], field.discriminantValue)); } CascadePointers(writer, found, ptrFields, union); if (isFiltered) { union.Pop(); } } break; } case Field.Unions.slot: { var slot = field.slot; if (!slot.type.IsValid()) { continue; } int len = slot.type.GetFieldLength(); if (len == Schema.Type.LEN_POINTER) { if (isFiltered) { union.Push(new UnionStub([email protected], field.discriminantValue)); } List <Tuple <Schema.Node, Schema.Field, Stack <UnionStub> > > fields; if (!ptrFields.TryGetValue((int)slot.offset, out fields)) { ptrFields.Add((int)slot.offset, fields = new List <Tuple <Schema.Node, Schema.Field, Stack <UnionStub> > >()); } fields.Add(Tuple.Create(node, field, Clone(union))); if (slot.type.Union == Schema.Type.Unions.@struct) { var found = writer.Lookup([email protected]); if (((Pointer)found).IsValid && found.IsGroup()) { CascadePointers(writer, found, ptrFields, union); } } if (isFiltered) { union.Pop(); } } break; } } } } }
public override CodeWriter WriteDiscriminant(Schema.Node node, Stack <UnionStub> union) { var @struct = node.@struct; WriteLine().Write("public "); if (union.Count != 0) { Write("new "); } Write("enum Unions"); Indent(); if (@struct.fields.IsValid()) { foreach (var field in @struct.fields) { if (field.discriminantValue != Field.noDiscriminant) { WriteLine().Write(Escape(field.name)).Write(" = ").Write(field.discriminantValue).Write(","); } } } Outdent(); WriteLine().Write("public ").Write(FullyQualifiedName(node)).Write(".Unions Union"); Indent(); WriteLine().Write("get"); Indent(); WriteLine().Write("return (").Write(FullyQualifiedName(node)).Write(".Unions)this.").Write(PointerName).Write(".GetUInt16("); WriteFieldOffset([email protected], union).Write(");"); Outdent(); WriteLine().Write("set"); Indent(); WriteLine().Write("this.").Write(PointerName).Write(".SetUInt16("); WriteFieldOffset([email protected], union).Write(", (ushort)value);"); Outdent(); //WriteLine().Write("set"); //Indent(); //ulong mask = ~((ulong)0xFFFF << byteInWord); //WriteLine().Write(node.IsGroup() ? "this.parent" : "this").Write(".").Write(DataPrefix).Write(wordIndex).Write(" = (") // .Write(node.IsGroup() ? "this.parent" : "this").Write(".").Write(DataPrefix).Write(wordIndex).Write(" & ").Write(mask).Write(") | "); //if (byteInWord == 0) Write("(ulong)value;"); //else Write("((ulong)value << ").Write(byteInWord).Write(");"); //Outdent(); //foreach(var field in @struct.fields) //{ // if(field.discriminantValue != Field.noDiscriminant && field.slot.type.Union == Schema.Type.Unions.@struct) // { // var found = Lookup([email protected]); // if(found != null && found.IsGroup()) // { // union.Push(new UnionStub(@struct.discriminantOffset, field.discriminantValue)); // union.Pop(); // } // } //} return(Outdent()); }
public abstract void WriteEnum(Schema.Node node);
public void WriteStruct(Schema.Node node, Stack <UnionStub> union) { if (node.IsGroup()) { return; } if (node.Union != Schema.Node.Unions.@struct) { return; } var @struct = node.@struct; // the nested type does not inherit the unions from the caller if (union.Count != 0) { union = new Stack <UnionStub>(); } BeginClass(node).WriteLittleEndianCheck(node); var fields = @struct.fields; int bodyWords = 0, pointerWords = 0; Schema.CodeGeneratorRequest.ComputeSpace(this, node, ref bodyWords, ref pointerWords); HashSet <ulong> nestedDone = null; if (fields.IsValid()) { foreach (var field in fields.OrderBy(x => x.codeOrder).ThenBy(x => x.name, Text.Comparer)) { bool pushed = false; if (field.discriminantValue != Field.noDiscriminant) { // write with union-based restructions union.Push(new UnionStub([email protected], field.discriminantValue)); pushed = true; } WriteFieldAccessor(node, field, union); // declare the struct too, if we need to - noting that it includes union-context Node child = default(Node); switch (field.Union) { case Field.Unions.group: child = Lookup(field.group.typeId); break; case Field.Unions.slot: if (field.slot.type.Union == Schema.Type.Unions.@struct) { child = Lookup([email protected]); } break; } if (child.IsValid()) { if (child.IsGroup()) { if (nestedDone == null) { nestedDone = new HashSet <ulong>(); } if (nestedDone.Add(child.id)) { WriteGroup(child, union); } } } if (pushed) { union.Pop(); } } } //if (node.nestedNodes != null) //{ // foreach (var nestedNode in node.nestedNodes) // { // if (nestedDone == null || !nestedDone.Contains(nestedNode.id)) // { // var found = Lookup(nestedNode.id); // if (found != null && found.IsGroup()) // { // WriteGroup(found, union); // WriteGroupAccessor(node, found, LocalName(found.displayName, false), false); // } // } // } //} if (@struct.discriminantCount != 0) { WriteDiscriminant(node, union); } DeclareFields(bodyWords, pointerWords); WriteNestedTypes(node, union); EndClass(); }
public abstract CodeWriter WriteFieldAccessor(Schema.Node parent, Schema.Field field, Stack <UnionStub> union);
public abstract CodeWriter WriteLittleEndianCheck(Schema.Node node);
public override CodeWriter WriteLittleEndianCheck(Schema.Node node) { return(this); }
public abstract CodeWriter WriteDiscriminant(Schema.Node node, Stack <UnionStub> union);
public abstract CodeWriter WriteGroup(Schema.Node node, Stack <UnionStub> union);
public abstract CodeWriter WriteGroupAccessor(Schema.Node parent, Schema.Node child, string name, bool extraNullable);
private void BeginProperty(Schema.Node type, string name, bool nullable) { WriteLine().Write("public "); Write(FullyQualifiedName(type)).Write(" ").Write(Escape(name)); Indent(); }
public abstract CodeWriter BeginClass(Schema.Node node);
public override CodeWriter WriteFieldAccessor(Schema.Node parent, Schema.Field field, Stack <UnionStub> union) { if (field.Union == Field.Unions.group) { var found = Lookup(field.group.typeId); if (!found.IsValid()) { return(WriteLine().Write("#warning no type for: " + field.name)); } return(WriteGroupAccessor(parent, found, field.name.ToString(), union.Count != 0)); } if (!field.slot.type.IsValid()) { return(WriteLine().Write("#warning no type for: " + field.name)); } var ordinal = field.ordinal; var slot = field.slot; var type = slot.type; var len = type.GetFieldLength(); if (len == 0) { return(this); } if (ordinal.Union == Schema.Field.ordinalGroup.Unions.@explicit) { WriteLine().Write("[").Write(typeof(FieldAttribute)).Write("(").Write(ordinal.@explicit); var offset = slot.offset; if (len == Schema.Type.LEN_POINTER) { Write(", pointer: ").Write(offset); } else { int o = (int)offset * len; Write(", ").Write(o).Write(", ").Write(o + len); } Write(")]"); } //bool extraNullable = union.Count != 0 && type.Union != Schema.Type.Unions.@struct; var grp = (len == Schema.Type.LEN_POINTER && type.Union == Schema.Type.Unions.@struct) ? Lookup([email protected]) : default(Node); if (grp.IsValid() && grp.IsGroup()) { return(WriteGroupAccessor(parent, grp, field.name.ToString(), false)); } if (slot.hadExplicitDefault) { WriteLine().Write("[").Write(typeof(System.ComponentModel.DefaultValueAttribute)).Write("(").Write(type, slot.defaultValue).Write(")]"); } BeginProperty(type, field.name.ToString(), false); WriteLine().Write("get"); Indent(); if (len == Schema.Type.LEN_POINTER) { // note: groups already handled WriteLine().Write("return (").Write(Format(slot.type)).Write(")this.").Write(PointerName).Write(".GetPointer("); WriteFieldOffset(slot.offset, union); Write(");"); } else { switch (type.Union) { case Schema.Type.Unions.@bool: WriteLine().Write("return "); if (slot.hadExplicitDefault && slot.defaultValue.Union == Schema.Value.Unions.@bool && slot.defaultValue.@bool) { Write("!"); } Write("this.").Write(PointerName).Write(".GetBoolean("); WriteFieldOffset(slot.offset, union).Write(");"); break; case Schema.Type.Unions.int8: case Schema.Type.Unions.uint8: case Schema.Type.Unions.int16: case Schema.Type.Unions.uint16: case Schema.Type.Unions.int32: case Schema.Type.Unions.uint32: case Schema.Type.Unions.int64: case Schema.Type.Unions.uint64: case Schema.Type.Unions.float32: case Schema.Type.Unions.float64: if (slot.hadExplicitDefault) { WriteLine().Write("return (").Write(Format(slot.type)).Write(")(this.").Write(PointerName).Write("."); } else { WriteLine().Write("return this.").Write(PointerName).Write("."); } switch (type.Union) { case Schema.Type.Unions.int8: Write("GetSByte"); break; case Schema.Type.Unions.uint8: Write("GetByte"); break; case Schema.Type.Unions.int16: Write("GetInt16"); break; case Schema.Type.Unions.uint16: Write("GetUInt16"); break; case Schema.Type.Unions.int32: Write("GetInt32"); break; case Schema.Type.Unions.uint32: Write("GetUInt32"); break; case Schema.Type.Unions.int64: Write("GetInt64"); break; case Schema.Type.Unions.uint64: Write("GetUInt64"); break; case Schema.Type.Unions.float32: Write("GetSingle"); break; case Schema.Type.Unions.float64: Write("GetDouble"); break; } Write("("); WriteFieldOffset(slot.offset, union).Write(")"); if (slot.hadExplicitDefault) { WriteXorDefaultValue(field.slot.defaultValue).Write(")"); } Write(";"); break; case Schema.Type.Unions.@enum: var e = Lookup([email protected]); if (!((Pointer)e).IsValid || e.Union != Schema.Node.Unions.@enum || !((Pointer)[email protected]).IsValid) { WriteLine().Write("#error enum not found: ").Write([email protected]); } else { // all enums are Int16; so 4 WriteLine().Write("return (").Write(FullyQualifiedName(e)).Write(")this.") .Write(PointerName).Write(".GetUInt16("); WriteFieldOffset(slot.offset, union).Write(");"); } break; default: WriteLine().Write("throw new global::System.NotImplementedException(); // ").Write(type.Union); break; } } Outdent(); WriteLine().Write("set"); Indent(); if (len == Schema.Type.LEN_POINTER) { WriteLine().Write("this.").Write(PointerName).Write(".SetPointer("); WriteFieldOffset(slot.offset, union).Write(", value);"); } else { switch (type.Union) { case Schema.Type.Unions.@bool: WriteLine().Write("this.").Write(PointerName).Write(".SetBoolean("); WriteFieldOffset(slot.offset, union).Write(", "); if (slot.hadExplicitDefault && slot.defaultValue.Union == Schema.Value.Unions.@bool && slot.defaultValue.@bool) { Write("!"); } Write("value);"); break; case Schema.Type.Unions.int8: case Schema.Type.Unions.uint8: case Schema.Type.Unions.int16: case Schema.Type.Unions.uint16: case Schema.Type.Unions.int32: case Schema.Type.Unions.uint32: case Schema.Type.Unions.int64: case Schema.Type.Unions.uint64: case Schema.Type.Unions.float32: case Schema.Type.Unions.float64: WriteLine().Write("this.").Write(PointerName).Write("."); switch (type.Union) { case Schema.Type.Unions.int8: Write("SetSByte"); break; case Schema.Type.Unions.uint8: Write("SetByte"); break; case Schema.Type.Unions.int16: Write("SetInt16"); break; case Schema.Type.Unions.uint16: Write("SetUInt16"); break; case Schema.Type.Unions.int32: Write("SetInt32"); break; case Schema.Type.Unions.uint32: Write("SetUInt32"); break; case Schema.Type.Unions.int64: Write("SetInt64"); break; case Schema.Type.Unions.uint64: Write("SetUInt64"); break; case Schema.Type.Unions.float32: Write("SetSingle"); break; case Schema.Type.Unions.float64: Write("SetDouble"); break; } Write("("); WriteFieldOffset(slot.offset, union); if (slot.hadExplicitDefault) { Write(", (").Write(Format(slot.type)).Write(")(value"); WriteXorDefaultValue(field.slot.defaultValue).Write("));"); } else { Write(", value);"); } break; case Schema.Type.Unions.@enum: var e = Lookup([email protected]); if (!((Pointer)e).IsValid || e.Union != Schema.Node.Unions.@enum || !((Pointer)[email protected]).IsValid) { WriteLine().Write("#error enum not found: ").Write([email protected]); } else { WriteLine().Write("this.").Write(PointerName).Write(".SetUInt16("); WriteFieldOffset(slot.offset, union).Write(", (ushort)value);"); } break; default: WriteLine().Write("throw new global::System.NotImplementedException(); // ").Write(type.Union); break; } } Outdent(); return(Outdent()); }
public override CodeWriter WriteGroup(Schema.Node node, Stack <UnionStub> union) { var parent = node; while (((Pointer)parent).IsValid && parent.IsGroup()) { parent = FindParent(parent); } if (!parent.IsValid()) { return(WriteLine().Write("#error parent not found for: ").Write(node.displayName)); } WriteLine().Write("[global::CapnProto.Group, global::CapnProto.Id(").Write(node.id).Write(")]"); WriteLine().Write("public partial struct ").Write(LocalName(node)); Indent(); WriteLine().Write("private ").Write(typeof(Pointer)).Write(" ").Write(PointerName).Write(";"); WriteLine().Write("internal ").Write(LocalName(node)).Write("(").Write(typeof(Pointer)).Write(" pointer)"); Indent(); WriteLine().Write("this.").Write(PointerName).Write(" = pointer;"); Outdent(); HashSet <ulong> nestedDone = null; if ([email protected]()) { foreach (var field in [email protected]) //.OrderBy(x => x.codeOrder).ThenBy(x => x.name, Text.Comparer)) { bool pushed = false; if (field.discriminantValue != Field.noDiscriminant) { // write with union-based restructions union.Push(new UnionStub([email protected], field.discriminantValue)); pushed = true; } WriteFieldAccessor(node, field, union); // declare the struct too, if we need to - noting that it includes union-context Node child = default(Node); switch (field.Union) { case Field.Unions.group: child = Lookup(field.group.typeId); break; case Field.Unions.slot: if (field.slot.type.Union == Schema.Type.Unions.@struct) { child = Lookup([email protected]); } break; } if (child.IsValid()) { if (child.IsGroup()) { if (nestedDone == null) { nestedDone = new HashSet <ulong>(); } if (nestedDone.Add(child.id)) { WriteGroup(child, union); } } } if (pushed) { union.Pop(); } } } if ([email protected] != 0) { WriteDiscriminant(node, union); } WriteNestedTypes(node, union); return(Outdent()); }