示例#1
0
 protected override void BuildItemWrite(CodeBlockNested b)
 {
     b
     .AppendCode("ResourceReference retVal = this.Value.ResourceReference();")
     ;
 }
示例#2
0
        bool DefineSliceOnValueDiscriminator(Int32 index,
                                             CodeBlockNested sliceDiscriminators,
                                             ElementDefinitionNode sliceNode,
                                             String varName,
                                             ElementDefinition.DiscriminatorComponent discriminator,
                                             String valueFilterMethod,
                                             String leafType)
        {
            const String fcn = nameof(DefineSliceOnValueDiscriminator);

            var     selectedNodes = sliceNode.Select(discriminator.Path).ToArray();
            var     fixedNodes    = selectedNodes.FixedValues().ToArray();
            Element fixedValue    = fixedNodes.SingleOrDefault();

            if (fixedValue == null)
            {
                this.gen.ConversionError(this.GetType().Name, fcn, $"Slice node lacks fixed element {discriminator.Path}");
                return(false);
            }

            String sliceName = sliceNode.Element.SliceName;

            CodeBlockNested valueMethodBlock = sliceClassMethods.AppendBlock();

            valueFilterMethod = CSMisc.ValueFilterName(CSMisc.MakePath(sliceNode.SlicePath(), discriminator.Path));
            // Note: We are defining method here, after we know the return value type.
            valueMethodBlock
            .BlankLine()
            .SummaryOpen()
            .AppendCode($"/// Return all elements for discriminator # {index+1}'")
            .SummaryLines(discriminator.ToFormatedJson())
            .SummaryClose()
            ;

            {
                GenerateFhirPathSearch g = new GenerateFhirPathSearch(this.gen);
                if (g.Generate(valueMethodBlock, "static", valueFilterMethod, elementNode, discriminator.Path, out Type leaf) == false)
                {
                    return(false);
                }
                leafType = leaf.FriendlyName();
            }


            String tempVarName = $"sliceOnValueDiscriminator";

            sliceDiscriminators
            .OpenBrace()
            .AppendLine($"/// Define discriminator'")
            .AppendLines("/// ", discriminator.ToFormatedJson().ToLines())
            .AppendCode($"var {tempVarName} = new SliceOnValueDiscriminator<{baseItemTypeName}, {leafType}>()")
            .OpenBrace()
            .AppendCode($"Path = \"{discriminator.Path}\",")
            .AppendCode($"ValueFilter = {valueFilterMethod}")
            .CloseBrace(";")
            ;

            ElementFixCode.Construct(sliceDiscriminators, fixedValue, $"{tempVarName}.Pattern", out String propertyType);

            sliceDiscriminators
            .AppendCode($"{varName} = {tempVarName};")
            .CloseBrace("")
            ;

            return(true);
        }
示例#3
0
 protected override void BuildItemRead(CodeBlockNested b)
 {
     b
     .AppendCode($"this.Value = ({this.ElementGetName}) doc.GetResource(item);")
     ;
 }
示例#4
0
        void GenerateCIMPLDataType(CodeBlockNested entryBlock,
                                   CodeBlockNested mapBlock,
                                   FHIRAllTypes fhirType)
        {
            String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);
            Type   fhirCSType   = ModelInfo.GetTypeForFhirType(fhirTypeName);

            entryBlock
            .BlankLine()
            .AppendLine($"// Fhir data element {fhirTypeName} definition")
            .AppendCode($"Entry: {fhirTypeName}")
            ;


            CodeBlockNested item = entryBlock.AppendBlock();
            CodeBlockNested vars = entryBlock.AppendBlock();

            foreach (PropertyInfo pi in fhirCSType.GetProperties())
            {
                FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>();
                if (attribute != null)
                {
                    String min;
                    String max;
                    Type   csType;
                    if (pi.PropertyType.IsList())
                    {
                        min    = "0";
                        max    = "*";
                        csType = pi.PropertyType.GenericTypeArguments[0];
                    }
                    if (pi.PropertyType.IsNullable())
                    {
                        min    = "0";
                        max    = "1";
                        csType = pi.PropertyType.GenericTypeArguments[0];
                    }
                    else
                    {
                        csType = pi.PropertyType;
                        min    = "1";
                        max    = "1";
                    }

                    String name = attribute.Name.ToMachineName();
                    item
                    .AppendCode($"Property: {name} {min}..{max}")
                    ;

                    String typeName   = null;
                    String csTypeName = csType.FriendlyName();
                    switch (csTypeName)
                    {
                    case "string":
                        OutputProperty(attribute, item, min, max);
                        break;

                    default:
                        typeName = ModelInfo.GetFhirTypeNameForType(pi.PropertyType);
                        if (String.IsNullOrEmpty(typeName))
                        {
                            throw new Exception($"Can not determine fhir type for c# type {csTypeName}");
                        }
                        break;
                    }

                    vars
                    .BlankLine()
                    .AppendCode($"Element: {name}")
                    .AppendCode($"Value: {typeName}")
                    ;

                    //    methods
                    //        .AppendCode($"case \"{attribute.Name}\":")
                    //        .OpenBrace()
                    //        .AppendCode($"ElementDefinition e = new ElementDefinition")
                    //        .OpenBrace()
                    //        .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",")
                    //        .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",")
                    //        .AppendCode($"Min = {min},")
                    //        .AppendCode($"Max = \"{max}\"")
                    //        .CloseBrace(";")
                    //        .AppendCode($"retVal = new ElementNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));")
                    //        .AppendCode($"retVal.AutoGeneratedFlag = true;")
                    //        .AppendCode($"break;")
                    //        .CloseBrace(";")
                    //        ;
                }
            }
        }
示例#5
0
        void CreateSliceAccessorClass(ElementDefinitionNode sliceNode,
                                      out String sliceClassName,
                                      out String sliceInterfaceName)
        {
            const String fcn = nameof(CreateSliceAccessorClass);

            String sliceName = sliceNode.Element.SliceName.ToMachineName();

            sliceClassName     = $"{sliceName}Impl";
            sliceInterfaceName = $"I{sliceName}";
            String sliceBaseClassName;
            String sliceBaseInterfaceName;
            String baseType = elementNode.FhirType.FriendlyName();

            // Debug.Assert(sliceClassName != "BreastradAbnormalityDensityImpl");

            switch (SliceAccessorType(sliceNode))
            {
            case SliceAccessorTypes.Error:
                sliceBaseClassName     = "??";
                sliceBaseInterfaceName = "??";
                break;

            case SliceAccessorTypes.Single:
                sliceBaseClassName     = $"SliceListAccessorSingle<{accessorType}>";
                sliceBaseInterfaceName = $"ISliceAccessorSingle<{accessorType}>";
                break;

            case SliceAccessorTypes.Multiple:
                sliceBaseClassName     = $"SliceListAccessorMultiple<{accessorType}>";
                sliceBaseInterfaceName = $"ISliceAccessorMultiple<{accessorType}>";
                break;

            default:
                throw new NotImplementedException("Unknown SliceAccessorTypes value");
            }

            String elementJson = sliceNode.Element.ToFormatedJson();

            this.subClassBlock
            .BlankLine()
            .SummaryOpen()
            .Summary($"public interface that implements the functionality of slice {sliceClassName}")
            .SummaryClose()
            .AppendCode($"public interface {sliceInterfaceName} : {sliceBaseInterfaceName}")
            .OpenBrace()
            .CloseBrace()
            .BlankLine()
            .SummaryOpen()
            .Summary($"private class that implements the functionality of slice {sliceClassName}")
            .Summary("")
            .Summary(elementJson.ToLines())
            .SummaryClose()
            .AppendCode($"class {sliceClassName} : {sliceBaseClassName}, {sliceInterfaceName}")
            .OpenBrace()
            .DefineBlock(out this.sliceStaticFields)
            .DefineBlock(out CodeBlockNested staticConstructorHeader)
            .DefineBlock(out this.sliceClassFields)
            .DefineBlock(out this.sliceClassMethods)
            .CloseBrace()
            ;

            staticConstructorHeader
            .SummaryOpen()
            .Summary("Static constructor")
            .SummaryClose()
            .AppendLine("[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Performance\", \"CA1810:Initialize reference type static fields inline\")]")
            .AppendCode($"static {sliceClassName}()")
            .OpenBrace()
            .DefineBlock(out this.sliceStaticConstructor)
            .CloseBrace()
            ;

            if (sliceName == null)
            {
                this.gen.ConversionError(this.GetType().Name, fcn, $"Slice node '{elementNode.FullPath()}' lacks slice name");
                retVal = false;
            }
            else
            {
                const String sliceFieldName = "slicing";

                CreateConstructor(sliceClassName, sliceFieldName);

                this.sliceStaticFields
                .BlankLine()
                .SummaryOpen()
                .Summary($"slicing discriminator for {elementNode.FullPath()} slice {sliceName}")
                .SummaryClose()
                .AppendCode($"static Slicing<{baseItemTypeName}> {sliceFieldName};")
                ;

                this.sliceStaticConstructor
                .BlankLine()
                ;

                this.sliceStaticConstructor
                .AppendLine("// Instantiate slicing discriminator")
                .OpenBrace()
                .AppendCode($"ISliceDiscriminator<{baseItemTypeName}>[] discriminators = ")
                .AppendCode($"    new ISliceDiscriminator<{baseItemTypeName}>[{discriminators.Length}];")
                ;

                for (Int32 i = 0; i < discriminators.Length; i++)
                {
                    if (DefineDiscriminator(i, this.sliceStaticConstructor, sliceNode, $"discriminators[{i}]", discriminators[i]) == false)
                    {
                        retVal = false;
                    }
                }

                this.sliceStaticConstructor
                .AppendCode($"{sliceFieldName} = new Slicing<{baseItemTypeName}>")
                .OpenBrace()
                .AppendCode($"Discriminators = discriminators")
                .CloseBrace(";")
                .CloseBrace()
                ;
            }

            // Recursively create code to set values that are fixed in object.
            // If a child object needs to be fixed, make sure that parent objects are created
            // as well.
            // i.e. if a.b.c = fix(...)
            // than we need to create a and a.b as well as setting a.b.c.
            void SetFixedValues(ElementDefinitionNode setNode,
                                String propertyPath)
            {
                Int32 varNum = 0;

                foreach (ElementDefinitionNode setNodeChild in setNode.ChildNodes)
                {
                    String childPropertyPath = $"{propertyPath}.{setNodeChild.PropertyName}";

                    String childItemTypeName = setNodeChild.FhirItemType.FriendlyName();
                    if (setNodeChild.IsFixed)
                    {
                        if (setNodeChild.IsListType)
                        {
                            String varName = $"var{varNum}";
                            varNum += 1;
                            ElementFixCode.Construct(sliceClassMethods, setNodeChild.Element.Fixed, $"{varName}", out String propertyType);
                            sliceClassMethods.AppendCode($"{childPropertyPath}.Add({varName});");
                        }
                        else
                        {
                            ElementFixCode.Construct(sliceClassMethods, setNodeChild.Element.Fixed, childPropertyPath, out String propertyType);
                        }
                    }
                    else if (setNodeChild.HasFixedChild)
                    {
                        String varName = $"var{varNum}";
                        varNum += 1;
                        sliceClassMethods.AppendCode($"{childItemTypeName} {varName} = new {childItemTypeName}();");
                        if (setNodeChild.IsListType)
                        {
                            sliceClassMethods.AppendCode($"{childPropertyPath}.Add({varName});");
                        }
                        else
                        {
                            sliceClassMethods.AppendCode($"{childPropertyPath} = {varName};");
                        }
                        SetFixedValues(setNodeChild, varName);
                    }
                    else if (setNodeChild.HasFixedSlice)
                    {
                        String varName = $"var{varNum}";
                        varNum += 1;
                        sliceClassMethods.AppendCode($"// {childItemTypeName} {varName} = xxyyz;");
                        //methods.AppendCode($"{childItemTypeName} {varName} = new {childItemTypeName}();");
                        //if (setNodeChild.IsListType)
                        //    methods.AppendCode($"{childPropertyPath}.Add({varName});");
                        //else
                        //    methods.AppendCode($"{childPropertyPath} = {varName};");
                        //SetFixedValues(setNodeChild, varName);
                    }
                }
            }

            sliceClassMethods
            .BlankLine()
            .SummaryOpen()
            .Summary($"Create and initialize a new item")
            .SummaryClose()
            .AppendCode($"protected override {accessorType} Create()")
            .OpenBrace()
            .AppendCode($"{accessorType} retVal = new {accessorType}();")
            ;
            SetFixedValues(sliceNode, "retVal");
            sliceClassMethods
            .AppendCode($"return retVal;")
            .CloseBrace()
            ;
        }
示例#6
0
        void GenerateFindCommonChildren()
        {
            CodeEditor editor = new CodeEditor();

            CodeBlockNested main = editor.Blocks.AppendBlock();

            main
            .AppendLine($"using System;")
            .AppendLine($"using System.Linq;")
            .AppendLine($"using System.Collections.Generic;")
            .AppendLine($"using System.Reflection;")
            .AppendLine($"using System.Text;")
            .AppendLine($"using FhirKhit.Tools;")
            .AppendLine($"using Hl7.Fhir.Introspection;")
            .AppendLine($"using Hl7.Fhir.Model;")
            .AppendLine($"using Hl7.Fhir.Support.Model;")
            .AppendLine($"using System.Diagnostics;")
            .AppendLine($"using Hl7.FhirPath;")
            .BlankLine()
#if FHIR_R3
            .AppendLine($"namespace FhirKhit.Tools.R3")
#elif FHIR_R4
            .AppendLine($"namespace FhirKhit.Tools.R4")
#endif
            .OpenBrace()
            .AppendCode($"public partial class ElementDefinitionNode")
            .OpenBrace()
            ;
            CodeBlockNested construct = main.AppendBlock();
            CodeBlockNested methods   = main.AppendBlock();

            main
            .CloseBrace()
            .CloseBrace()
            ;

            construct
            .SummaryOpen()
            .Summary($"Create ElementDefinitionNode for child of common/primitive Fhir data type elements")
            .SummaryClose()
            .AppendCode($"public ElementDefinitionNode FindCommonChild(String parentPath, String childName)")
            .OpenBrace()
            .AppendCode($"switch (this.FhirItemType.FriendlyName())")
            .OpenBrace()
            ;

            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Ratio);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Period);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Range);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Attachment);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Identifier);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Annotation);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.HumanName);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.CodeableConcept);

            GenerateFindCommonChild(construct, methods, FHIRAllTypes.ContactPoint);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Coding);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Money);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Address);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Timing);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Quantity);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.SampledData);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Signature);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Age);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Distance);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Duration);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Count);
#if FHIR_R4
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.MoneyQuantity);
#endif
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.SimpleQuantity);
            GenerateFindCommonChild(construct, methods, FHIRAllTypes.Extension);

            construct
            .AppendCode($"default: return null;")
            .CloseBrace()
            .CloseBrace()
            ;

#if FHIR_R3
            String outputPath = Path.Combine(DirHelper.FindParentDir("Tools"),
                                             "FhirKhit.Tools.R3",
                                             "ElementDefinitionNode.FindChild.cs");
#elif FHIR_R4
            String outputPath = Path.Combine(DirHelper.FindParentDir("Tools"),
                                             "FhirKhit.Tools.R4",
                                             "ElementDefinitionNode.FindChild.cs");
#endif
            editor.Save(outputPath);
        }
示例#7
0
        void GenerateFindCommonChild(CodeBlockNested construct,
                                     CodeBlockNested methods,
                                     FHIRAllTypes fhirType)
        {
            String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);
            Type   fhirCSType   = ModelInfo.GetTypeForFhirType(fhirTypeName);

            String methodName = $"FindChild{fhirTypeName}";

            construct
            .AppendCode($"case \"{fhirCSType.FriendlyName()}\": return {methodName}(parentPath, childName);")
            ;

            methods
            .BlankLine()
            .SummaryOpen()
            .Summary($"Manually add the children of a Coding element.")
            .SummaryClose()
            .AppendCode($"ElementDefinitionNode {methodName}(String parentPath, String childName)")
            .OpenBrace()
            .AppendCode($"ElementDefinitionNode retVal;")
            .AppendCode($"switch (childName)")
            .OpenBrace()
            ;

            foreach (PropertyInfo pi in fhirCSType.GetProperties())
            {
                FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>();
                if (attribute != null)
                {
                    String min;
                    String max;
                    if (pi.PropertyType.IsList())
                    {
                        min = "0";
                        max = "*";
                    }
                    if (pi.PropertyType.IsNullable())
                    {
                        min = "0";
                        max = "1";
                    }
                    else
                    {
                        min = "1";
                        max = "1";
                    }
                    String varName = $"{attribute.Name}Var";
                    methods
                    .AppendCode($"case \"{attribute.Name}\":")
                    .OpenBrace()
                    .AppendCode($"ElementDefinition e = new ElementDefinition")
                    .OpenBrace()
                    .AppendCode($"Path = $\"{{parentPath}}.{attribute.Name}\",")
                    .AppendCode($"Short = \"{fhirType}.{attribute.Name} common attribute\",")
                    .AppendCode($"Min = {min},")
                    .AppendCode($"Max = \"{max}\"")
                    .CloseBrace(";")
                    .AppendCode($"retVal = new ElementDefinitionNode(this, e, typeof({pi.PropertyType.FriendlyName()}), nameof({fhirCSType.FriendlyName()}.{pi.Name}));")
                    .AppendCode($"retVal.AutoGeneratedFlag = true;")
                    .AppendCode($"break;")
                    .CloseBrace(";")
                    ;
                }
            }

            methods
            .AppendCode($"default: return null;")
            .CloseBrace()
            .AppendCode($"this.childNodeDictionary.Add(childName, retVal);")
            .AppendCode($"return retVal;")
            .CloseBrace()
            ;
        }
 protected override void BuildItemWrite(CodeBlockNested b)
 {
     b
     .AppendCode($"{this.FhirClassName} retVal = this.Value.WriteMember(doc);")
     ;
 }
 protected override void BuildItemRead(CodeBlockNested b)
 {
     b
     .AppendCode($"this.Value = ({this.ElementGetName}) item.Value;")
     ;
 }
示例#10
0
        void FixElement(CodeBlockNested code,
                        PropertyInfo pi,
                        String varName,
                        String retValName)
        {
            //FhirElementAttribute attribute = pi.GetCustomAttribute<FhirElementAttribute>();
            //if (attribute == null)
            //    return;
            //if (attribute.IsPrimitiveValue)
            //{
            //    FixElementPrimitive(code, pi, varName, attribute);
            //    return;
            //}

            FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>();

            if (attribute == null)
            {
                return;
            }


            String name = pi.PropertyType.FriendlyName();

            code.AppendCode($"block.AppendCode(\"// Set {pi.Name} of type {name})\");");
            switch (name)
            {
            case "Element":
            case "Extension":
            case "ResourceReference":
            case "List<Extension>":
            case "List<Element>":
            case "List<ResourceReference>":
                return;

            case "bool?":
                code
                .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else if ({varName}.{pi.Name}.Value == true)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = true;\");")
                .AppendCode($"else")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = false;\");")
                ;
                break;

            case "byte[]":
                code
                .AppendCode($"if ({varName}.{pi.Name} == null)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else")
                .OpenBrace()
                .AppendCode($"block.OpenBrace();")
                .AppendCode($"block.AppendCode($\"byte[] data = new byte[]\");")
                .AppendCode($"block.OpenBrace();")
                .AppendCode($"Int32 i = 0;")
                .AppendCode($"while (i < {varName}.{pi.Name}.Length)")
                .OpenBrace()
                .AppendCode($"Int32 j = 0;")
                .AppendCode($"StringBuilder sb = new StringBuilder();")
                .AppendCode($"while ((i < {varName}.{pi.Name}.Length) && (j < 32))")
                .OpenBrace()
                .AppendCode($"sb.Append($\"{{{varName}.{pi.Name}[i]}}\");")
                .AppendCode($"if (i < {varName}.{pi.Name}.Length - 1) sb.Append(\",\");")
                .AppendCode($"j += 1;")
                .AppendCode($"i += 1;")
                .CloseBrace()
                .AppendCode($"block.AppendCode($\"{{sb.ToString()}}\");")
                .CloseBrace()
                .AppendCode($"block.CloseBrace(\";\");")
                .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = data;\");")
                .AppendCode($"block.CloseBrace(\";\");")
                .CloseBrace()
                ;
                break;

            case "DateTimeOffset?":
                code
                .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else")
                .OpenBrace()
                .AppendCode($"DateTimeOffset x = {varName}.{pi.Name}.Value;")
                .AppendCode($"block")
                .AppendCode($"    .AppendCode($\"{retValName}.{pi.Name} = new DateTimeOffset({{x.Year}}, {{x.Month}}, {{x.Day}},\")")
                .AppendCode($"    .AppendCode($\"    {{x.Hour}}, {{x.Minute}}, {{x.Second}}, {{x.Millisecond}},\")")
                .AppendCode($"    .AppendCode($\"    new TimeSpan({{x.Offset.Hours}}, {{x.Offset.Minutes}}, {{x.Offset.Seconds}}));\")")
                .AppendCode($";")
                .CloseBrace()
                ;
                break;

            case "decimal?":
                code
                .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new Nullable<decimal>((decimal) {{{varName}.{pi.Name}.Value}});\");")
                ;
                break;

            case "int?":
                code
                .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new Nullable<int>((int) {{{varName}.{pi.Name}.Value}});\");")
                ;
                break;

            case "string":
                code
                .AppendCode($"if ({varName}.{pi.Name} == null)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                .AppendCode($"else")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = \\\"{{{varName}.{pi.Name}}}\\\";\");")
                ;
                break;

            default:
                if (name.StartsWith("Code<"))
                {
                    String enumName = pi.PropertyType.GenericTypeArguments[0].FriendlyName();
                    code
                    .AppendCode($"if ({varName}.{pi.Name} == null)")
                    .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                    .AppendCode($"else")
                    .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new {name}({enumName}.{{{varName}.{pi.Name}.Value}});\");")
                    ;
                }
                else if (name.StartsWith("List<"))
                {
                    String source       = TempName();
                    String target       = TempName();
                    Type   listType     = pi.PropertyType.GenericTypeArguments[0];
                    String listTypeName = listType.FriendlyName();

                    code
                    .AppendCode($"if ({varName}.{pi.Name} == null)")
                    .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                    .AppendCode($"else")
                    .OpenBrace()
                    .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = new {name}();\");")
                    .AppendCode($"foreach (var {source} in {varName}.{pi.Name})")
                    .OpenBrace()
                    .AppendCode($"block.OpenBrace();")
                    .AppendCode($"block.AppendCode(\"var {target} = new {listTypeName}();\");")
                    ;

                    this.FixElements(code, listType, $"{source}", $"{target}");

                    code
                    .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name}.Add({target});\");")
                    .AppendCode($"block.CloseBrace();")
                    .CloseBrace()
                    .CloseBrace()
                    ;
                }
                else if (name.EndsWith("?"))
                {
                    Type   nullableType     = pi.PropertyType.GenericTypeArguments[0];
                    String nullableTypeName = nullableType.FriendlyName();
                    if (nullableType.IsEnum)
                    {
                        code
                        .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                        .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                        .AppendCode($"else")
                        .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = {nullableTypeName}.{{{varName}.{pi.Name}.Value}};\");")
                        ;
                    }
                    else if (nullableType.IsClass)
                    {
                        code
                        .AppendCode($"if ({varName}.{pi.Name}.HasValue == false)")
                        .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                        .AppendCode($"else")
                        .OpenBrace()
                        .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new {nullableTypeName}();\");")
                        ;
                        this.FixElements(code, nullableType, $"{varName}.{pi.Name}", $"{retValName}.{pi.Name}");
                        code
                        .CloseBrace()
                        ;
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    String typeName = pi.PropertyType.FriendlyName();
                    code
                    .AppendCode($"if ({varName}.{pi.Name} == null)")
                    .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = null;\");")
                    .AppendCode($"else")
                    .OpenBrace()
                    .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new {typeName}();\");")
                    ;
                    this.FixElements(code, pi.PropertyType, $"{varName}.{pi.Name}", $"{retValName}.{pi.Name}");
                    code
                    .CloseBrace()
                    ;
                }
                return;
            }
        }
示例#11
0
        public void FhirConstructB()
        {
            CodeEditor editor = new CodeEditor();

            CodeBlockNested main = editor.Blocks.AppendBlock();

            main
            .AppendLine($"using System;")
            .AppendLine($"using System.Linq;")
            .AppendLine($"using System.Collections.Generic;")
            .AppendLine($"using System.Reflection;")
            .AppendLine($"using System.Text;")
            .AppendLine($"using FhirKhit.ProfGen.PGShared;")
            .AppendLine($"using FhirKhit.ProfGen.PGShared.CodeGen.CSApi.Extensions;")
            .AppendLine($"using FhirKhit.Tools;")
            .AppendLine($"using Hl7.Fhir.Introspection;")
            .AppendLine($"using Hl7.Fhir.Model;")
            .AppendLine($"using Hl7.Fhir.Support.Model;")
            .AppendLine($"using System.Diagnostics;")
            .AppendLine($"using Hl7.FhirPath;")
            .BlankLine()
            .AppendLine($"namespace FhirKhit.ProfGen.GenTests")
            .OpenBrace()
            .AppendCode($"public class FhirConstructUse")
            .OpenBrace()
            ;
            CodeBlockNested construct = main.AppendBlock();
            CodeBlockNested methods   = main.AppendBlock();

            main
            .CloseBrace()
            .CloseBrace()
            ;

            construct
            .AppendLine($"/// <summary>")
            .AppendLine($"/// generate code for eqch fhri element. Makes sure it compiles.")
            .AppendLine($"/// </summary>")
            .AppendCode($"public void Use()")
            .OpenBrace()
            .BlankLine()
            ;

            Int32 varNum = 0;

            foreach (FHIRAllTypes fhirType in Enum.GetValues(typeof(FHIRAllTypes)).OfType <FHIRAllTypes>())
            {
                Trace.WriteLine($"fhirType {fhirType}");
                String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);
                Type   fhirCSType   = ModelInfo.GetTypeForFhirType(fhirTypeName);

                if (ModelInfo.IsPrimitive(fhirType))
                {
                    String varName1    = $"x{++varNum}";
                    String methodName1 = $"Method{++varNum}";

                    construct
                    .AppendCode($"{fhirCSType} {varName1} = {methodName1}();")
                    ;

                    Element fix = CreateFix(fhirCSType);
                    FhirConstruct.Construct(methods, fix, methodName1, out String propertyType1);
                }
                else if (ModelInfo.IsDataType(fhirType))
                {
                    if (Ignore(fhirType) == false)
                    {
                        String varName1    = $"x{++varNum}";
                        String methodName1 = $"Method{++varNum}";

                        construct
                        .AppendCode($"{fhirCSType} {varName1} = {methodName1}();")
                        ;

                        Element fix = CreateFix(fhirCSType);
                        FhirConstruct.Construct(methods, fix, methodName1, out String propertyType1);
                    }
                }
            }

            construct
            .CloseBrace()
            ;


#if FHIR_R2
            String outputPath = Path.Combine(DirHelper.FindParentDir("Projects"),
                                             "ProfGen",
                                             "R2",
                                             "FhirKhit.ProfGen.GenTests.R2",
                                             "Generated",
                                             "FhirConstructUse.cs");
#elif FHIR_R3
            String outputPath = Path.Combine(DirHelper.FindParentDir("Projects"),
                                             "ProfGen",
                                             "R3",
                                             "FhirKhit.ProfGen.GenTests.R3",
                                             "Generated",
                                             "FhirConstructUse.cs");
#elif FHIR_R4
            String outputPath = Path.Combine(DirHelper.FindParentDir("Projects"),
                                             "ProfGen",
                                             "R4",
                                             "FhirKhit.ProfGen.GenTests.R4",
                                             "Generated",
                                             "FhirConstructUse.cs");
#endif
            editor.Save(outputPath);
        }
示例#12
0
        void ProcessProperty(Int32 indent,
                             CodeBlockNested classBlock,
                             CodeBlockNested propertiesBlock,
                             CodeBlockNested mapBlock,
                             String entryPath)
        {
            const string fcn = "ProcessProperty";

            ElementDefinition ed = this.elements[this.elementIndex++];

            // Note: Currently we do not handle extensions.
            if (ed.Path.LastPathPart() == "extension")
            {
                return;
            }
            if (ed.Path.LastPathPart() == "modifierExtension")
            {
                return;
            }

            if (String.IsNullOrEmpty(ed.SliceName) == false)
            {
                this.gen.ConversionWarn(this.GetType().Name, fcn, "Ignoring slice");
            }
            if (ed.Slicing != null)
            {
                this.gen.ConversionWarn(this.GetType().Name, fcn, "Ignoring slicing");
            }

            //if (ed.Fixed != null)
            //    throw new ConvertErrorException(this.GetType().Name, fcn, $"Unexpected Fixed in element {ed.Path}.");
            //if (ed.Pattern != null)
            //    throw new ConvertErrorException(this.GetType().Name, fcn, $"Unexpected Pattern in element {ed.Path}.");

            String propertyName = this.gen.UniquePropertyName(ed, out bool createFlag);

            String fullPropertyName;
            String propertyPath = $"{entryPath}.{propertyName}";

            if (this.ContainsType(ed, BackboneElementStr))
            {
                if (ed.Type.Count != 1)
                {
                    throw new ConvertErrorException(this.GetType().Name, fcn, $"Backbone element {ed.Path} has multiple types.");
                }
                if (this.HasChildren(ed) == false)
                {
                    throw new ConvertErrorException(this.GetType().Name, fcn, $"Backbone element {ed.Path} has no children.");
                }

                fullPropertyName = this.ProcessSubEntry(indent + 1, ed.Path, propertyPath, "Group", "Group", BackboneElementStr, $"Group definition of {ed.Path}", null);
            }
            else if (this.ContainsType(ed, ElementStr))
            {
                if (ed.Type.Count != 1)
                {
                    throw new ConvertErrorException(this.GetType().Name, fcn, $"Element {ed.Path} has multiple types.");
                }
                if (this.HasChildren(ed) == false)
                {
                    throw new ConvertErrorException(this.GetType().Name, fcn, $"Element {ed.Path} has no children.");
                }

                fullPropertyName = this.ProcessSubEntry(indent + 1, ed.Path, propertyPath, "Group", "Group", ElementStr, $"Group definition of {ed.Path}", null);
            }
            else
            {
                fullPropertyName = propertyName;
                if (createFlag)
                {
                    if (this.gen.IsSliceField(ed.Path))
                    {
                        propertiesBlock
                        .BlankLine()
                        .AppendLine($"// Entry definition of {ed.Path}")
                        .AppendCode($"Group: {propertyName}Slices")
                        .AppendCode($"Property: {propertyName}Slice 0..*")
                        .BlankLine()
                        .AppendCode($"Group: {propertyName}Slice")
                        .AppendCode($"Property: {propertyName} 1..1")
                        .BlankLine()
                        .AppendCode($"Element: {propertyName}")
                        ;
                    }
                    else
                    {
                        propertiesBlock
                        .BlankLine()
                        .AppendLine($"// Entry definition of {ed.Path}")
                        .AppendCode($"Element: {propertyName}")
                        ;
                    }

                    HashSet <String> outputTypes = new HashSet <string>();
                    bool             firstFlag   = true;
                    void OutputType(String pType)
                    {
                        if (outputTypes.Contains(pType))
                        {
                            return;
                        }
                        outputTypes.Add(pType);
                        if (firstFlag)
                        {
                            propertiesBlock.AppendCode($"Value: {pType}");
                        }
                        else
                        {
                            propertiesBlock.AppendCode($"    or {pType}");
                        }
                        firstFlag = false;
                    }

                    {
                        String basePropertyPath = propertyPath.SkipFirstPathPart();
                        String baseEdPath       = ed.Path.SkipFirstPathPart();
                        if (this.gen.IsSliceField(ed.Path))
                        {
                            mapBlock.AppendCode($"    {basePropertyPath}Slices.{basePropertyPath}Slice.{basePropertyPath} maps to {baseEdPath}");
                        }
                        else
                        {
                            mapBlock.AppendCode($"    {basePropertyPath} maps to {baseEdPath}");
                        }
                    }
                    foreach (ElementDefinition.TypeRefComponent type in ed.Type)
                    {
                        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":
                            OutputType($"{type.Code}");
                            break;

                        case "CodeableConcept":
                        case "Coding":
                        case "code":
                            OutputType($"concept");
                            break;

                        case "uuid":
                        case "url":
                        case "canonical":
                            OutputType($"uri");
                            break;

                        case "Reference":
                            if (type.Profile.Any())
                            {
                                throw new ConvertErrorException(this.GetType().Name, fcn, $"Unexpected profile in type {ed.Path}:{type.Code}.");
                            }
                            if (type.TargetProfile.Count() == 0)
                            {
                                this.gen.AddAbbreviatedResource(ResourceStr);
                                OutputType($"Resource");
                            }
                            else
                            {
                                foreach (string target in type.TargetProfile)
                                {
                                    this.gen.AddAbbreviatedResource(target);
                                    String targetEntryName = target.LastUriPart().ToMachineName();
                                    OutputType($"{targetEntryName}");
                                }
                            }
                            break;

                        default:

                            if (type.Profile.Count() == 0)
                            {
                                this.gen.AddAbbreviatedResource(type.Code);
                                OutputType($"{type.Code.ToMachineName()}");
                            }
                            else
                            {
                                foreach (string profile in type.Profile)
                                {
                                    this.gen.AddAbbreviatedResource(profile);
                                    String profileName = profile.LastUriPart().ToMachineName();
                                    OutputType($"{profileName}");
                                }
                            }
                            break;
                        }
                    }
                }
            }

            if (this.gen.IsSliceField(ed.Path))
            {
                classBlock.AppendCode($"Property: {fullPropertyName}Slices 0..1");
            }
            else
            {
                classBlock.AppendCode($"Property: {fullPropertyName} {ed.Min}..{ed.Max}");
            }
        }
示例#13
0
        /// <summary>
        /// Create new file containing the definition for the new item.
        /// The new entry is created in its own namespace.
        /// </summary>
        String ProcessSubEntry(Int32 indent,
                               String elementPath,
                               String entryPath,
                               String suffix,
                               String typeName,
                               String parent,
                               String description,
                               String comment)
        {
            CodeBlockNested classBlock = entryEditor.Blocks.AppendBlock();
            CodeBlockNested propertydefinitionsBlock = entryEditor.Blocks.AppendBlock();
            CodeBlockNested mapBlock = mapEditor.Blocks.AppendBlock();

            String entryName = this.gen.GetFieldMap(elementPath);

            if (String.IsNullOrEmpty(suffix) == false)
            {
                entryName += suffix;
                entryPath += suffix;
            }
            classBlock
            .BlankLine()
            .AppendComment(comment)
            .AppendCode($"{typeName}: {entryName}")
            ;

            if (indent == 0)
            {
                mapBlock
                .BlankLine()
                .AppendCode($"{entryPath} maps to {elementPath}:")
                ;
            }
            else
            {
                mapBlock
                .BlankLine()
                .AppendCode($"    {entryPath.SkipFirstPathPart()} maps to {elementPath.SkipFirstPathPart()}")
                ;
            }

            switch (parent)
            {
            case null:
            case ResourceStr:
            case BackboneElementStr:
            case ElementStr:
                break;

            default:
                this.gen.AddResource(parent);
                classBlock.AppendCode($"Parent: {parent}");
                break;
            }
            classBlock
            .AppendCode($"Description: \"{description}\"")
            ;

            while (this.elementIndex < this.elements.Length)
            {
                ElementDefinition subElement = this.elements[this.elementIndex];
                if (subElement.Path.StartsWith($"{elementPath}.") == false)
                {
                    break;
                }
                this.ProcessProperty(indent, classBlock, propertydefinitionsBlock, mapBlock, entryPath);
            }

            return(entryName);
        }
示例#14
0
        //$$$ Delete
        /// <summary>
        /// Traverse children using simple fhir path query.
        /// Return selected elements, or null if not found.
        /// </summary>
        public bool Generate(CodeBlockNested block,
                             String methodModifiers,
                             String methodName,
                             ElementDefinitionNode node,
                             String path,
                             out Type leafType)
        {
            const String fcn = nameof(Generate);

            if (block is null)
            {
                throw new ArgumentNullException(nameof(block));
            }
            if (methodModifiers is null)
            {
                throw new ArgumentNullException(nameof(methodModifiers));
            }
            if (methodName is null)
            {
                throw new ArgumentNullException(nameof(methodName));
            }
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (path is null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            //String fhirTypeName = node.FhirType.FriendlyName();
            String fhirItemTypeName = node.FhirItemType.FriendlyName();
            // we need to write header after we determine leaf node type.
            CodeBlockNested methodHeaderBlock = block.AppendBlock();

            block
            .OpenBrace()
            .BlankLine()
            ;

            childBlock = block.AppendBlock();

            String[] pathItems = path.Split('.');
            Int32    i         = 0;

            if (pathItems[0] == node.Name)
            {
                i += 1;
            }

            Int32 resultCounter = 0;

            leafType = null;
            String resultThis = "head";

            while (i < pathItems.Length)
            {
                resultCounter += 1;
                String resultNext = $"result{resultCounter}";

                String pathItem = pathItems[i++];
                if (pathItem.StartsWith("resolve("))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("extension(\""))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else if (pathItem.StartsWith("ofType("))
                {
                    this.gen.ConversionError(this.GetType().Name, fcn, $"TODO: FhirPath operator {pathItem} not implemented");
                    return(false);
                }
                else
                {
                    if (node.TryGetAnyChild(pathItem, out ElementDefinitionNode next) == false)
                    {
                        this.gen.ConversionError(this.GetType().Name, fcn, $"Child {pathItem} not found");
                        return(false);
                    }

                    Type         nodeType          = node.FhirItemType;
                    PropertyInfo childProperty     = nodeType.GetPropertyByFhirName(pathItem);
                    String       childPropertyName = childProperty.Name;
                    String       childMethodName   = GenerateGetChild(childPropertyName, nodeType, childProperty.PropertyType);

                    block.AppendCode($"IEnumerable<{next.FhirItemType.FriendlyName()}> {resultNext} = {childMethodName}({resultThis});");
                    resultThis = resultNext;
                    node       = next;
                }
            }

            block
            .AppendCode($"return {resultThis};")
            .CloseBrace()
            ;

            leafType = node.FhirItemType;

            methodHeaderBlock
            .AppendCode($"{methodModifiers} IEnumerable<{leafType.FriendlyName()}> {methodName}(IEnumerable<{fhirItemTypeName}> head)")
            ;
            return(true);
        }
示例#15
0
        void ProcessFhirResource(SDefInfo sDefInfo)
        {
            const String fcn = "ProcessFhirResource";

            StructureDefinition sDef = sDefInfo.SDef;

            ClearSDef(sDef);

            this.ConversionInfo(this.GetType().Name, fcn, $"Processing Resource {sDef.Name} {sDefInfo.TFlag}");

            String          instanceName   = ResourceName(sDef.Name);
            CodeEditor      instanceEditor = this.project.CreateEditor(Path.Combine(ResourceGenPath, $"{instanceName}.cs"));
            CodeBlockNested instanceBlock  = instanceEditor.Blocks.AppendBlock();

            instanceBlock
            .AppendCode("using System;")
            .AppendCode("using System.Diagnostics;")
            .AppendCode("using System.IO;")
            .AppendCode("using System.Linq;")
            .AppendCode("using Hl7.Fhir.Model;")
            .BlankLine()
            .AppendCode($"namespace {ResourceNameSpace}")
            .OpenBrace()
            .AppendCode("#region Json")
            .AppendCode("#if NEVER")
            .AppendLines("", sDef.ToFormatedJson().ToLines())
            .AppendLine("#endif")
            .AppendCode("#endregion")
            .SummaryOpen()
            .Summary($"Fhir resource '{sDef.Name}'")
            .SummaryClose()
            .DefineBlock(out CodeBlockNested classBlock)
            .CloseBrace()
            ;

            String baseClass = ResourceBase;

            if (String.IsNullOrEmpty(sDef.BaseDefinition) == false)
            {
                String name = this.ResourceName(sDef.BaseDefinition.LastUriPart());
                baseClass = $"{ResourceNameSpace}.{name}";
            }
            Int32 i = 0;

            DefineClass(classBlock,
                        sDef.Differential.Element.ToArray(),
                        ref i,
                        sDef.Differential.Element[0].Path,
                        instanceName,
                        baseClass,
                        out CodeBlockNested constructorBlock);

            constructorBlock
            .AppendCode($"this.Name = \"{sDef.Name}\";")
            .AppendCode($"this.Uri = \"{sDef.Url}\";")
            ;

            if (i != sDef.Differential.Element.Count)
            {
                throw new ConvertErrorException(this.GetType().Name, fcn, $"Internal error. Invalid element index");
            }
        }
示例#16
0
        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;
                }
            }
        }