void DefineClass(CodeBlockNested block, ElementDefinition[] elements, ref Int32 index, String basePath, String className, String parentMakerClassName, out CodeBlockNested constructorBlock) { basePath += '.'; block .AppendComment($"{index}. {elements[index].Path}") .AppendCode($"public partial class {className} : {parentMakerClassName}") .OpenBrace() .DefineBlock(out CodeBlockNested subClassBlock) .DefineBlock(out CodeBlockNested fieldsBlock) .BlankLine() .AppendCode($"public override void Write(Hl7.Fhir.Model.StructureDefinition sDef)") .OpenBrace() .AppendCode($"base.Write(sDef);") .AppendCode($"sDef.Differential.Element.Add(new Hl7.Fhir.Model.ElementDefinition") .OpenBrace() .AppendCode($"Path = \"{elements[index].Path}\",") .AppendCode($"ElementId = \"{elements[index].ElementId}\"") .CloseBrace(");") .DefineBlock(out CodeBlockNested writeBlock) .CloseBrace() .BlankLine() .AppendCode($"public {className}()") .OpenBrace() .DefineBlock(out constructorBlock) .CloseBrace() .CloseBrace() ; index += 1; DefineClassFields(subClassBlock, fieldsBlock, constructorBlock, writeBlock, elements, basePath, className, ref index); }
void DefineClassFields( CodeBlockNested subClassBlock, CodeBlockNested fieldsBlock, CodeBlockNested constructorBlock, CodeBlockNested writeBlock, ElementDefinition[] elements, String basePath, String className, ref Int32 index) { while (index < elements.Length) { ElementDefinition ed = elements[index]; // We know when we are at the end of a sub class, when the // path does no longer start with subPath. String path = ed.Path; if (ed.Path.StartsWith(basePath) == false) { return; } path = path.Substring(basePath.Length); String elementName = ElementName(ed.Path.LastPathPart()); fieldsBlock .AppendComment($"{index}. {elements[index].Path}") .AppendCode($"public ElementDefinitionInfo {elementName};") ; writeBlock .AppendCode($"{elementName}.Write(sDef);") ; Int32 min = 0; Int32 max = -1; if (ed.Min.HasValue) { min = ed.Min.Value; } if ((String.IsNullOrEmpty(ed.Max) == false) && (ed.Max != "*")) { max = Int32.Parse(ed.Max); } constructorBlock .OpenBrace() .AppendComment($"{index}. {elements[index].Path}") .AppendCode($"this.{elementName} = new ElementDefinitionInfo") .OpenBrace() .AppendCode($"Name = \"{elementName}\",") .AppendCode($"Path= \"{ed.Path}\",") .AppendCode($"Id = \"{ed.ElementId}\",") .AppendCode($"Min = {min},") .AppendCode($"Max = {max},") .AppendCode($"Types = new BaseType[]") .OpenBrace() .DefineBlock(out CodeBlockNested typesBlock) .CloseBrace("") .CloseBrace(";") .CloseBrace("") ; // If next elements starts with this items path, then this is a // subelement, so start creating sub class. if ( (index < elements.Length - 1) && (elements[index + 1].Path.StartsWith($"{ed.Path}.")) ) { String subClassName = TypeName(path.LastPathPart()); typesBlock .AppendCode($"new {subClassName}") .OpenBrace() .CloseBrace() ; DefineClass(subClassBlock, elements, ref index, ed.Path, subClassName, ComplexBase, out CodeBlockNested dummy); } else { for (Int32 typeIndex = 0; typeIndex < ed.Type.Count; typeIndex += 1) { String sep = typeIndex == (ed.Type.Count - 1) ? "" : ","; ElementDefinition.TypeRefComponent type = ed.Type[typeIndex]; switch (type.Code) { case null: break; case "boolean": case "integer": case "decimal": case "uri": case "string": case "base64Binary": case "instant": case "date": case "dateTime": case "time": case "oid": case "id": case "markdown": case "unsignedInt": case "positiveInt": case "xhtml": case "code": case "uuid": case "url": case "canonical": { String sep1 = ""; typesBlock .AppendCode($"new {PrimitiveNameSpace}.{PrimitiveName(type.Code)}") .OpenBrace() .AppendProfiles(type.Profile, ref sep1) .AppendTargetProfiles(type.TargetProfile, ref sep1) .CloseBrace(sep) ; } sep = ", "; break; case "CodeableConcept": case "Coding": { String sep1 = ""; typesBlock .AppendCode($"new {ComplexNameSpace}.{TypeName(type.Code)}") .OpenBrace() .AppendProfiles(type.Profile, ref sep1) .AppendTargetProfiles(type.TargetProfile, ref sep1) .CloseBrace(sep) ; } sep = ", "; break; case "Resource": { String sep1 = ""; typesBlock .AppendCode($"new {ResourceNameSpace}.{ResourceName(type.Code)}") .OpenBrace() .AppendProfiles(type.Profile, ref sep1) .AppendTargetProfiles(type.TargetProfile, ref sep1) .CloseBrace(sep) ; } sep = ", "; break; case "Reference": { String sep1 = ""; typesBlock .AppendCode($"new {ComplexNameSpace}.{TypeName(type.Code)}") .OpenBrace() .AppendProfiles(type.Profile, ref sep1) .AppendTargetProfiles(type.TargetProfile, ref sep1) .CloseBrace(sep) ; } sep = ", "; break; default: typesBlock .AppendCode($"new {ComplexNameSpace}.{TypeName(type.Code)}") .OpenBrace() .CloseBrace(sep) ; sep = ", "; break; } } index += 1; } } }