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(); }