Example #1
0
        void ConstructDataType(CodeBlockNested methods,
                               CodeBlockNested construct,
                               FHIRAllTypes fhirType)
        {
            if (GenerateCommon.Ignore(fhirType))
            {
                return;
            }

            this.tempCounter = 0;
            String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);
            Type   csType       = ModelInfo.GetTypeForFhirType(fhirTypeName);
            String csTypeName   = csType.FriendlyName();

            construct
            .AppendCode($"case \"{fhirTypeName}\": // {fhirType}  - DataType")
            .OpenBrace()
            .AppendCode($"propertyType = \"{fhirTypeName}\";")
            .AppendCode($"return Construct(block, ({csTypeName})fix, varName);")
            .CloseBrace()
            .BlankLine()
            ;

            CodeBlockNested m = methods.AppendBlock();

            m
            .BlankLine()
            .AppendLine($"/// <summary>")
            .AppendLine($"/// Return c# text to create indicated element.")
            .AppendLine($"/// </summary>")
            .AppendCode($"static public bool Construct(CodeBlockNested block,")
            .AppendCode($"    {csTypeName} fix,")
            .AppendCode($"    String varName)")
            .OpenBrace()
            //.AppendCode($"const String fcn = \"Construct({fhirTypeName})\";")
            .BlankLine()
            .AppendCode($"if (block is null)")
            .AppendCode($"    throw new ArgumentNullException(nameof(block));")
            .AppendCode($"block")
            .AppendCode($"    .OpenBrace()")
            .AppendCode($"    .AppendCode(\"{csTypeName} temp = new {csTypeName}();\")")
            .AppendCode($"    ;")
            .AppendCode($"if (fix != null)")
            .OpenBrace()
            ;

            FixElements(m, csType, "fix", "temp");

            m
            .CloseBrace()
            .AppendCode($"block")
            .AppendCode($"    .AppendCode($\"{{varName}} = temp;\")")
            .AppendCode($"    .CloseBrace()")
            .AppendCode($"    ;")
            .AppendCode($"return  true;")
            .CloseBrace()
            ;
        }
        void ConstructDataType(CodeBlockNested methods,
                               CodeBlockNested construct,
                               FHIRAllTypes fhirType)
        {
            if (Ignore(fhirType))
            {
                return;
            }

            String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);
            Type   csType       = ModelInfo.GetTypeForFhirType(fhirTypeName);
            String csTypeName   = csType.FriendlyName();

            construct
            .AppendCode($"case \"{fhirTypeName}\": // {fhirType}  - DataType")
            .OpenBrace()
            .AppendCode($"propertyType = \"{fhirTypeName}\";")
            .AppendCode($"return Construct(block, ({csTypeName})fix, methodName, methodAccess);")
            .CloseBrace()
            .BlankLine()
            ;

            CodeBlockNested m = methods.AppendBlock();

            m
            .BlankLine()
            .AppendLine($"/// <summary>")
            .AppendLine($"/// Return c# text to create indicated element.")
            .AppendLine($"/// </summary>")
            .AppendCode($"static public bool Construct(CodeBlockNested block,")
            .AppendCode($"    {csTypeName} fix,")
            .AppendCode($"    String methodName,")
            .AppendCode($"    String methodAccess = \"public\")")
            .OpenBrace()
            //.AppendCode($"const String fcn = \"Construct({fhirTypeName})\";")
            .BlankLine()
            .AppendCode($"block")
            .AppendCode($"    .AppendCode($\"{{methodAccess}} {csTypeName} {{methodName}}()\")")
            .AppendCode($"    .OpenBrace()")
            .AppendCode($"    .AppendCode(\"{csTypeName} retVal = new {csTypeName}();\")")
            .AppendCode($"    ;")
            .AppendCode($"if (fix != null)")
            .OpenBrace()
            ;

            FixElements(m, csType, "fix", "retVal");

            m
            .CloseBrace()
            .AppendCode($"block")
            .AppendCode($"    .AppendCode(\"return retVal;\")")
            .AppendCode($"    .CloseBrace()")
            .AppendCode($"    ;")
            .AppendCode($"return  true;")
            .CloseBrace()
            ;
        }
Example #3
0
        // Generate GetChild method.
        String GenerateGetChild(string childPropertyName,
                                Type inputType,
                                Type outputType)
        {
            if (childPropertyName is null)
            {
                throw new ArgumentNullException(nameof(childPropertyName));
            }

            String inputTypeBaseName = inputType.FriendlyName();

            childMethodCounter += 1;
            String childMethodName = $"GetChild_{childMethodCounter}";
            String outputTypeItemName;

            if (outputType.IsList())
            {
                outputTypeItemName = outputType.GenericTypeArguments[0].FriendlyName();
            }
            else
            {
                outputTypeItemName = outputType.FriendlyName();
            }

            childBlock
            .AppendCode($"IEnumerable<{outputTypeItemName}> {childMethodName}(IEnumerable<{inputTypeBaseName}> inputElements)")
            .OpenBrace()
            .AppendCode($"if (inputElements != null)")
            .OpenBrace()
            .AppendCode($"foreach ({inputTypeBaseName} inputElement in inputElements)")
            .OpenBrace()
            ;

            if (outputType.IsList())
            {
                childBlock
                .AppendCode($"foreach ({outputType.FriendlyName()} childElement in inputElement.{childPropertyName})")
                .OpenBrace()
                .AppendCode($"yield return childElement;")
                .CloseBrace()
                ;
            }
            else
            {
                childBlock
                .AppendCode($"yield return inputElement.{childPropertyName};")
                ;
            }

            childBlock
            .CloseBrace()
            .CloseBrace()
            .CloseBrace()
            ;
            return(childMethodName);
        }
Example #4
0
        /// <summary>
        /// Generate Construct method.
        /// </summary>
        public void Generate(String outputPath)
        {
            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()
            .AppendLine($"namespace FhirKhit.SliceGen.CSApi")
            .OpenBrace()
            .SummaryOpen()
            .Summary("This class will generate code to create an element that has the same values as the passed value.")
            .Summary("This class was automatically generated by GenerateFixCodes.cs.")
            .Summary("Do not hand modify this file!")
            .SummaryClose()
            .AppendLine($"public static class ElementFixCode")
            .OpenBrace()
            ;
            CodeBlockNested construct = main.AppendBlock();
            CodeBlockNested methods   = main.AppendBlock();

            main
            .CloseBrace()
            .CloseBrace()
            ;

            construct
            .AppendLine("static String CleanString(String s) => s.Replace(\"\\\"\", \"\\\\\\\"\");")
            .AppendLine($"/// <summary>")
            .AppendLine($"/// Return c# text to create indicated element.")
            .AppendLine($"/// </summary>")
            .AppendLine($"static public bool Construct(CodeBlockNested block,")
            .AppendCode($"    Element fix,")
            .AppendCode($"    String varName,")
            .AppendCode($"    out String propertyType)")
            .OpenBrace()
            //.AppendCode($"const String fcn = \"Construct\";")
            .BlankLine()
            .AppendCode($"if (fix is null)")
            .AppendCode($"    throw new ArgumentNullException(nameof(fix));")
            .AppendCode($"propertyType = null;")
            .AppendCode($"switch (fix.TypeName)")
            .OpenBrace()
            ;

            foreach (FHIRAllTypes fhirType in Enum.GetValues(typeof(FHIRAllTypes)).OfType <FHIRAllTypes>())
            {
                String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);

                if (ModelInfo.IsPrimitive(fhirType))
                {
                    ConstructPrimitive(methods, construct, fhirType);
                }
                else if (ModelInfo.IsDataType(fhirType))
                {
                    ConstructDataType(methods, construct, fhirType);
                }
            }

            construct
            .CloseBrace()
            .AppendCode($"return false;")
            .CloseBrace()
            ;

            editor.Save(outputPath);
        }
Example #5
0
        void FixElement(CodeBlockNested code,
                        PropertyInfo pi,
                        String varName,
                        String retValName)
        {
            FhirElementAttribute attribute = pi.GetCustomAttribute <FhirElementAttribute>();

            if (attribute == null)
            {
                return;
            }

            String name = pi.PropertyType.FriendlyName();

            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 == true)")
                .OpenBrace()
                .AppendCode($"if ({varName}.{pi.Name}.Value == true)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = true;\");")
                .AppendCode($"else")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = false;\");")
                .CloseBrace()
                ;
                break;

            case "byte[]":
                code
                .AppendCode($"if ({varName}.{pi.Name} != null)")
                .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 == true)")
                .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 == true)")
                .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = new Nullable<decimal>((decimal) {{{varName}.{pi.Name}.Value}});\");")
                ;
                break;

            case "int?":
                code
                .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)")
                .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} = \\\"{{CleanString({varName}.{pi.Name})}}\\\";\");")
                ;
                break;

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

                    code
                    .AppendCode($"if ({varName}.{pi.Name} != null)")
                    .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 (pi.PropertyType.IsNullable())
                {
                    Type   nullableType     = pi.PropertyType.GenericTypeArguments[0];
                    String nullableTypeName = nullableType.FriendlyName();
                    if (nullableType.IsEnum)
                    {
                        code
                        .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)")
                        .AppendCode($"    block.AppendCode($\"{retValName}.{pi.Name} = {nullableTypeName}.{{{varName}.{pi.Name}.Value}};\");")
                        ;
                    }
                    else if (nullableType.IsClass)
                    {
                        code
                        .AppendCode($"if ({varName}.{pi.Name}.HasValue == true)")
                        .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)")
                    .OpenBrace()
                    .AppendCode($"block.AppendCode($\"{retValName}.{pi.Name} = new {typeName}();\");")
                    ;
                    this.FixElements(code, pi.PropertyType, $"{varName}.{pi.Name}", $"{retValName}.{pi.Name}");
                    code
                    .CloseBrace()
                    ;
                }
                return;
            }
        }
Example #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);
        }
 /// <summary>
 /// end Create common static constructor method.
 /// </summary>
 public static CodeBlockNested WriteInitEnd(this CodeBlockNested block)
 {
     block.CloseBrace();
     return(block);
 }
Example #8
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);
        }
Example #9
0
        public void FhirConstructA()
        {
            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.CSApi")
            .OpenBrace()
            .AppendLine($"public static class FhirConstruct")
            .OpenBrace()
            ;
            CodeBlockNested construct = main.AppendBlock();
            CodeBlockNested methods   = main.AppendBlock();

            main
            .CloseBrace()
            .CloseBrace()
            ;

            construct
            .AppendLine($"/// <summary>")
            .AppendLine($"/// Return c# text to create indicated element.")
            .AppendLine($"/// </summary>")
            .AppendLine($"static public bool Construct(CodeBlockNested block,")
            .AppendCode($"    Element fix,")
            .AppendCode($"    String methodName,")
            .AppendCode($"    out String propertyType)")
            .OpenBrace()
            //.AppendCode($"const String fcn = \"Construct\";")
            .BlankLine()
            .AppendCode($"propertyType = null;")
            .AppendCode($"switch (fix.TypeName)")
            .OpenBrace()
            ;

            foreach (FHIRAllTypes fhirType in Enum.GetValues(typeof(FHIRAllTypes)).OfType <FHIRAllTypes>())
            {
                String fhirTypeName = ModelInfo.FhirTypeToFhirTypeName(fhirType);

                if (ModelInfo.IsPrimitive(fhirType))
                {
                    ConstructPrimitive(methods, construct, fhirType);
                }
                else if (ModelInfo.IsDataType(fhirType))
                {
                    ConstructDataType(methods, construct, fhirType);
                }
            }

            construct
            .CloseBrace()
            .AppendCode($"return false;")
            .CloseBrace()
            ;

            String outputPath = Path.Combine(DirHelper.FindParentDir("Projects"),
                                             "ProfGen",
                                             "PGShared",
                                             "FhirKhit.ProfGen.PGShared",
                                             "CodeGen",
                                             "CSApi",
                                             "FhirConstruct.cs");

            editor.Save(outputPath);
        }