/// <summary>Writes an element.</summary> /// <param name="complex">The complex.</param> /// <param name="element">The element.</param> private void WriteElement( FhirComplex complex, FhirElement element) { Dictionary <string, string> values = element.NamesAndTypesForExport( FhirTypeBase.NamingConvention.PascalCase, FhirTypeBase.NamingConvention.PascalCase, false, string.Empty, complex.Components.ContainsKey(element.Path)); foreach (KeyValuePair <string, string> kvp in values) { string elementName; if (kvp.Key == complex.Name) { elementName = $"{kvp.Key}Field"; } else { elementName = kvp.Key; } string optionalFlagString = (element.IsOptional && IsNullable(kvp.Value)) ? "?" : string.Empty; if (!string.IsNullOrEmpty(element.Comment)) { WriteIndentedComment(element.Comment); } string elementType = element.IsArray ? $"List<{kvp.Value}{optionalFlagString}>" : $"{kvp.Value}{optionalFlagString}"; string camel = FhirUtils.ToConvention(kvp.Key, string.Empty, FhirTypeBase.NamingConvention.CamelCase); _writer.WriteLineIndented($"[JsonProperty(\"{camel}\")]"); _writer.WriteLineIndented($"public {elementType} {elementName} {{ get; set; }}"); if (RequiresExtension(kvp.Value)) { _writer.WriteLineIndented($"[JsonProperty(\"_{camel}\")]"); if (element.IsArray) { _writer.WriteLineIndented($"public List<Element> _{elementName} {{ get; set; }}"); } else { _writer.WriteLineIndented($"public Element _{elementName} {{ get; set; }}"); } } } }
/// <summary>Writes a code.</summary> /// <param name="element">The element.</param> private void WriteCode( FhirElement element) { string codeName = FhirUtils.ToConvention( $"{element.Path}.Codes", string.Empty, FhirTypeBase.NamingConvention.PascalCase); if (codeName.Contains("[x]")) { codeName = codeName.Replace("[x]", string.Empty); } if (codeName.Contains("[X]")) { codeName = codeName.Replace("[X]", string.Empty); } if (_exportedCodes.Contains(codeName)) { return; } _exportedCodes.Add(codeName); _writer.WriteLineIndented($"/// <summary>"); _writer.WriteLineIndented($"/// Code Values for the {element.Path} field"); _writer.WriteLineIndented($"/// </summary>"); if (codeName.EndsWith("Codes", StringComparison.Ordinal)) { _writer.WriteLineIndented($"public static class {codeName} {{"); } else { _writer.WriteLineIndented($"public static class {codeName}Codes {{"); } _writer.IncreaseIndent(); foreach (string code in element.Codes) { FhirUtils.SanitizeForCode(code, _reservedWords, out string name, out string value); _writer.WriteLineIndented($"public const string {name.ToUpperInvariant()} = \"{value}\";"); } _writer.DecreaseIndent(); _writer.WriteLineIndented("}"); }
/// <summary>Writes a code.</summary> /// <param name="element">The element.</param> private void WriteCode( FhirElement element) { string codeName = FhirUtils.ToConvention( $"{element.Path}.Codes", string.Empty, FhirTypeBase.NamingConvention.PascalCase); if (codeName.Contains("[x]")) { codeName = codeName.Replace("[x]", string.Empty); } if (_exportedCodes.Contains(codeName)) { return; } _exportedCodes.Add(codeName); _writer.WriteLineIndented($"/**"); _writer.WriteLineIndented($" * Code Values for the {element.Path} field"); _writer.WriteLineIndented($" */"); _writer.WriteLineIndented($"export enum {codeName} {{"); _writer.IncreaseIndent(); foreach (string code in element.Codes) { FhirUtils.SanitizeForCode(code, _reservedWords, out string name, out string value); _writer.WriteLineIndented($"{name.ToUpperInvariant()} = \"{value}\","); } _writer.DecreaseIndent(); _writer.WriteLineIndented("}"); }
/// <summary>Writes a value set.</summary> /// <param name="vs">The value set.</param> private void WriteValueSet( FhirValueSet vs) { string vsName = FhirUtils.SanitizeForProperty(vs.Id ?? vs.Name, _reservedWords); vsName = FhirUtils.SanitizedToConvention(vsName, FhirTypeBase.NamingConvention.PascalCase); if (!string.IsNullOrEmpty(vs.Description)) { WriteIndentedComment(vs.Description); } else { WriteIndentedComment($"Value Set: {vs.URL}|{vs.Version}"); } if (vsName.EndsWith("ValueSet", StringComparison.Ordinal)) { _writer.WriteLineIndented($"public static class {vsName}"); } else { _writer.WriteLineIndented($"public static class {vsName}ValueSet"); } _writer.WriteLineIndented("{"); _writer.IncreaseIndent(); bool prefixWithSystem = vs.ReferencedCodeSystems.Count > 1; HashSet <string> usedValues = new HashSet <string>(); foreach (FhirConcept concept in vs.Concepts.OrderBy(c => c.Code)) { string input = concept.Display; if (_systemsNamedByDisplay.Contains(concept.System)) { input = concept.Display; } else if (_systemsNamedByCode.Contains(concept.System)) { input = concept.Code; } else if (string.IsNullOrEmpty(input)) { input = concept.Code; } string codeName = FhirUtils.SanitizeForProperty(input, _reservedWords); string codeValue = FhirUtils.SanitizeForValue(concept.Code); codeName = FhirUtils.SanitizedToConvention(codeName, FhirTypeBase.NamingConvention.PascalCase); string name; if (prefixWithSystem) { name = $"{codeName}_{concept.SystemLocalName}"; } else { name = codeName; } if (usedValues.Contains(name)) { // start at 2 so that the unadorned version makes sense as v1 for (int i = 2; i < 1000; i++) { if (usedValues.Contains($"{name}_{i}")) { continue; } name = $"{name}_{i}"; break; } } usedValues.Add(name); if (_namesRequiringKeywordNew.Contains(name)) { _writer.WriteLineIndented($"public static readonly new Coding {name} = new Coding"); } else { _writer.WriteLineIndented($"public static readonly Coding {name} = new Coding"); } _writer.WriteLineIndented("{"); _writer.IncreaseIndent(); _writer.WriteLineIndented($"Code = \"{codeValue}\","); if (!string.IsNullOrEmpty(concept.Display)) { _writer.WriteLineIndented($"Display = \"{FhirUtils.SanitizeForQuoted(concept.Display)}\","); } _writer.WriteLineIndented($"System = \"{concept.System}\""); _writer.DecreaseIndent(); _writer.WriteLineIndented("};"); } _writer.DecreaseIndent(); _writer.WriteLineIndented("};"); }
/// <summary>Writes a value set.</summary> /// <param name="vs"> The value set.</param> /// <param name="writtenCodesAndNames">[in,out] The written codes, to prevent duplication /// without writing all code systems.</param> /// <param name="writtenNames"> [in,out] List of names of the writtens.</param> private void WriteValueSet( FhirValueSet vs, ref Dictionary <string, WrittenCodeInfo> writtenCodesAndNames, ref HashSet <string> writtenNames) { string vsName = FhirUtils.SanitizeForProperty(vs.Id ?? vs.Name, _reservedWords); vsName = FhirUtils.SanitizedToConvention(vsName, FhirTypeBase.NamingConvention.PascalCase); foreach (FhirConcept concept in vs.Concepts.OrderBy(c => c.Code)) { if (writtenCodesAndNames.ContainsKey(concept.Key())) { continue; } string input = concept.Display; if (_systemsNamedByDisplay.Contains(concept.System)) { input = concept.Display; } else if (_systemsNamedByCode.Contains(concept.System)) { input = concept.Code; } else if (string.IsNullOrEmpty(input)) { input = concept.Code; } string codeName = FhirUtils.SanitizeForProperty(input, _reservedWords); string codeValue = FhirUtils.SanitizeForValue(concept.Code); codeName = FhirUtils.SanitizedToConvention(codeName, FhirTypeBase.NamingConvention.PascalCase); string constName; if (!string.IsNullOrEmpty(concept.SystemLocalName)) { constName = $"{concept.SystemLocalName}_{codeName}"; } else { constName = $"{vsName}_{codeName}"; } if (writtenNames.Contains(constName)) { // start at 2 so that the unadorned version makes sense as v1 for (int i = 2; i < 1000; i++) { if (writtenNames.Contains($"{constName}_{i}")) { continue; } constName = $"{constName}_{i}"; break; } } writtenCodesAndNames.Add( concept.Key(), new WrittenCodeInfo() { Name = codeName, ConstName = constName }); writtenNames.Add(constName); _writer.WriteLineIndented($"const {constName}: Coding = {{"); _writer.IncreaseIndent(); _writer.WriteLineIndented($"code: \"{codeValue}\","); if (!string.IsNullOrEmpty(concept.Display)) { _writer.WriteLineIndented($"display: \"{FhirUtils.SanitizeForQuoted(concept.Display)}\","); } _writer.WriteLineIndented($"system: \"{concept.System}\""); _writer.DecreaseIndent(); _writer.WriteLineIndented("};"); } if (!string.IsNullOrEmpty(vs.Description)) { WriteIndentedComment(vs.Description); } else { WriteIndentedComment($"Value Set: {vs.URL}|{vs.Version}"); } _writer.WriteLineIndented($"export const {vsName} = {{"); _writer.IncreaseIndent(); bool prefixWithSystem = vs.ReferencedCodeSystems.Count > 1; HashSet <string> usedValues = new HashSet <string>(); // TODO: shouldn't loop over this twice, but writer functions don't allow writing in two places at once yet foreach (FhirConcept concept in vs.Concepts.OrderBy(c => c.Code)) { string codeKey = concept.Key(); if (!string.IsNullOrEmpty(concept.Definition)) { WriteIndentedComment(concept.Definition); } string name; if (prefixWithSystem) { name = $"{writtenCodesAndNames[codeKey].Name}_{concept.SystemLocalName}"; } else { name = writtenCodesAndNames[codeKey].Name; } if (usedValues.Contains(name)) { // start at 2 so that the unadorned version makes sense as v1 for (int i = 2; i < 1000; i++) { if (usedValues.Contains($"{name}_{i}")) { continue; } name = $"{name}_{i}"; break; } } usedValues.Add(name); _writer.WriteLineIndented($"{name}: {writtenCodesAndNames[codeKey].ConstName},"); } _writer.DecreaseIndent(); _writer.WriteLineIndented("};"); }