Skip to content

Commit 46e8169

Browse files
authored
Merge pull request #68 from FirelyTeam/merge-dev-sdk6-in-main-sdk5
Merge dev sdk6 in main sdk5
2 parents c49d34f + 0b736ae commit 46e8169

12 files changed

Lines changed: 831 additions & 981 deletions

File tree

.run/firely-all.run.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="firely-all" type="CompoundRunConfigurationType">
3+
<toRun name="fhir-codegen: Firely 5.x Base" type="LaunchSettings" />
4+
<toRun name="fhir-codegen: Firely 5.x Conformance" type="LaunchSettings" />
5+
<toRun name="fhir-codegen: Firely 5.x R4" type="LaunchSettings" />
6+
<toRun name="fhir-codegen: Firely 5.x R4B" type="LaunchSettings" />
7+
<toRun name="fhir-codegen: Firely 5.x R5" type="LaunchSettings" />
8+
<toRun name="fhir-codegen: Firely 5.x STU3" type="LaunchSettings" />
9+
<method v="2" />
10+
</configuration>
11+
</component>

src/Microsoft.Health.Fhir.CodeGen/Language/Firely/CSharpFirely2.cs

Lines changed: 700 additions & 890 deletions
Large diffs are not rendered by default.

src/Microsoft.Health.Fhir.CodeGen/Language/Firely/CSharpFirelyCommon.cs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
// </copyright>
55

66
using System.ComponentModel;
7+
using System.Text;
78
using Hl7.Fhir.Model;
89
using Microsoft.Health.Fhir.CodeGen.FhirExtensions;
10+
using Microsoft.Health.Fhir.CodeGenCommon.Extensions;
11+
using Microsoft.Health.Fhir.CodeGenCommon.Packaging;
12+
using Microsoft.Health.Fhir.CodeGenCommon.Utils;
913

1014
#if NETSTANDARD2_0
1115
using Microsoft.Health.Fhir.CodeGenCommon.Polyfill;
@@ -17,7 +21,7 @@ public static class CSharpFirelyCommon
1721
{
1822

1923
/// <summary>Dictionary mapping FHIR primitive types to language equivalents (see Template-Model.tt#1252).</summary>
20-
public static readonly Dictionary<string, string> PrimitiveTypeMap = new Dictionary<string, string>()
24+
public static readonly Dictionary<string, string> PrimitiveTypeMap = new()
2125
{
2226
{ "base64Binary", "byte[]" },
2327
{ "boolean", "bool?" },
@@ -61,22 +65,6 @@ public static class CSharpFirelyCommon
6165
{ "Resource", "DomainResource" },
6266
};
6367

64-
/// <summary>Primitive types that have a specific validation attribute on their Value property.</summary>
65-
public static readonly Dictionary<string, string> PrimitiveValidationPatterns = new()
66-
{
67-
["uri"] = "UriPattern",
68-
["uuid"] = "UuidPattern",
69-
["id"] = "IdPattern",
70-
["date"] = "DatePattern",
71-
["dateTime"] = "DateTimePattern",
72-
["oid"] = "OidPattern",
73-
["code"] = "CodePattern",
74-
["time"] = "TimePattern",
75-
["string"] = "StringPattern",
76-
["markdown"] = "StringPattern",
77-
["xhtml"] = "NarrativeXhtmlPattern"
78-
};
79-
8068
/// <summary>
8169
/// Determines the subset of code to generate.
8270
/// </summary>
@@ -251,4 +239,27 @@ public static int GetOrder(int relativeOrder)
251239
{
252240
return (relativeOrder * 10) + 10;
253241
}
242+
243+
public static string BuildOpenAllowedTypesAttribute() => "[AllowedTypes(OpenChoice = true)]";
244+
245+
public static string BuildAllowedTypesAttribute(IEnumerable<TypeReference> types, FhirReleases.FhirSequenceCodes? since)
246+
{
247+
StringBuilder sb = new();
248+
sb.Append("[AllowedTypes(");
249+
250+
string typesList = string.Join(",",
251+
types.Select(t => $"typeof({t.PropertyTypeString})"));
252+
253+
sb.Append(typesList);
254+
if (since is not null)
255+
sb.Append($", Since = FhirRelease.{since}");
256+
sb.Append(")]");
257+
return sb.ToString();
258+
}
259+
}
260+
261+
262+
public static class StringHelpers
263+
{
264+
public static string EnsurePeriod(this string s) => s.EndsWith('.') ? s : s + ".";
254265
}

src/Microsoft.Health.Fhir.CodeGen/Language/Firely/FirelyNetIG.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ private void ProcessAndWriteValueSets()
724724
foreach ((string unversionedUrl, string[] versions) in _info.ValueSetVersions.OrderBy(kvp => kvp.Key))
725725
{
726726
// check for exclusions
727-
if (CSharpFirely2._exclusionSet.Contains(unversionedUrl))
727+
if (CSharpFirely2.ExclusionSet.Contains(unversionedUrl))
728728
{
729729
continue;
730730
}
@@ -808,7 +808,7 @@ private void ProcessAndWriteValueSet(
808808

809809
// Enums and their containing classes cannot have the same name,
810810
// so we have to correct these here
811-
if (CSharpFirely2._enumNamesOverride.TryGetValue(vs.Url, out var replacementName))
811+
if (CSharpFirely2.EnumNamesOverride.TryGetValue(vs.Url, out var replacementName))
812812
{
813813
nameSanitized = replacementName;
814814
}
@@ -2159,9 +2159,9 @@ private void WriteProfile(StructureDefinition sd)
21592159
break;
21602160
//throw new Exception($"Found multiple discriminators for {id}");
21612161
}
2162-
2162+
21632163
if (discriminators.Length == 1)
2164-
{
2164+
{
21652165
discriminator = discriminators[0];
21662166

21672167
bool isExtensionSlice = _findExtensionPathRegex.IsMatch(discriminator.Path);
@@ -3361,7 +3361,7 @@ private ExtensionData GetExtensionData(
33613361
remarks = (remarks == null ? string.Empty : remarks + "\n") +
33623362
$"Structure Definition Name: {cd.Structure.Name}";
33633363
}
3364-
3364+
33653365
string directive;
33663366
if (_info.TryGetPackageSource(cd.Structure, out string packageId, out string packageVersion))
33673367
{
@@ -3567,7 +3567,7 @@ private ExtensionData GetExtensionData(
35673567
Expression = "DataType",
35683568
},
35693569
ContextTarget = null,
3570-
ContextElementInfo = new("", "", "", new ChoiceTypeReference(), null),
3570+
ContextElementInfo = new("", "", "", ComplexTypeReference.DataTypeReference, null),
35713571
//ContextElementInfo = new CSharpFirely2.WrittenElementInfo()
35723572
//{
35733573
// ElementType = "Hl7.Fhir.Model.DataType",

src/Microsoft.Health.Fhir.CodeGen/Language/Firely/TypeReference.cs

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
#nullable enable
2-
31
using Microsoft.Health.Fhir.CodeGenCommon.Extensions;
42
using Microsoft.Health.Fhir.CodeGenCommon.Utils;
53

64
namespace Microsoft.Health.Fhir.CodeGen.Language.Firely;
75

86
public abstract record TypeReference(string Name)
97
{
8+
public static TypeReference BuildFromFhirTypeName(string name, string? vsName=null, string? vsClass=null)
9+
{
10+
// Elements of type Code or Code<T> have their own naming/types, so handle those separately.
11+
if (name == "code" && vsName is not null)
12+
return new CodedTypeReference(vsName, vsClass);
13+
14+
if (PrimitiveTypeReference.IsFhirPrimitiveType(name))
15+
return PrimitiveTypeReference.GetTypeReference(name);
16+
17+
// Otherwise, this is a "normal" name for a complex type.
18+
return new ComplexTypeReference(name, MapTypeName(name));
19+
}
20+
1021
public abstract string PropertyTypeString { get; }
1122

1223
internal static string MapTypeName(string name)
@@ -43,27 +54,42 @@ public record PrimitiveTypeReference(string Name, string PocoTypeName, Type Conv
4354
public static PrimitiveTypeReference ForTypeName(string name, Type propertyType) =>
4455
new(name, MapTypeName(name), propertyType);
4556

57+
public static readonly PrimitiveTypeReference PrimitiveType = ForTypeName("PrimitiveType", typeof(object));
58+
public static readonly PrimitiveTypeReference Boolean = ForTypeName("boolean", typeof(bool));
59+
public static readonly PrimitiveTypeReference Base64Binary = ForTypeName("base64Binary", typeof(byte[]));
60+
public static readonly PrimitiveTypeReference Canonical = ForTypeName("canonical", typeof(string));
61+
public static readonly PrimitiveTypeReference Code = ForTypeName("code", typeof(string));
62+
public static readonly PrimitiveTypeReference Date = ForTypeName("date", typeof(string));
63+
public static readonly PrimitiveTypeReference DateTime = ForTypeName("dateTime", typeof(string));
64+
public static readonly PrimitiveTypeReference Decimal = ForTypeName("decimal", typeof(decimal));
65+
public static readonly PrimitiveTypeReference Id = ForTypeName("id", typeof(string));
66+
public static readonly PrimitiveTypeReference Instant = ForTypeName("instant", typeof(DateTimeOffset));
67+
public static readonly PrimitiveTypeReference Integer = ForTypeName("integer", typeof(int));
68+
public static readonly PrimitiveTypeReference Integer64 = ForTypeName("integer64", typeof(long));
69+
public static readonly PrimitiveTypeReference Oid = ForTypeName("oid", typeof(string));
70+
public static readonly PrimitiveTypeReference PositiveInt = ForTypeName("positiveInt", typeof(int));
71+
public static readonly PrimitiveTypeReference String = ForTypeName("string", typeof(string));
72+
public static readonly PrimitiveTypeReference Time = ForTypeName("time", typeof(string));
73+
public static readonly PrimitiveTypeReference UnsignedInt = ForTypeName("unsignedInt", typeof(int));
74+
public static readonly PrimitiveTypeReference Uri = ForTypeName("uri", typeof(string));
75+
public static readonly PrimitiveTypeReference Url = ForTypeName("url", typeof(string));
76+
public static readonly PrimitiveTypeReference Xhtml = ForTypeName("xhtml", typeof(string));
77+
public static readonly PrimitiveTypeReference Markdown = ForTypeName("markdown", typeof(string));
78+
4679
public static readonly IReadOnlyCollection<PrimitiveTypeReference> PrimitiveList =
4780
[
48-
ForTypeName("base64Binary", typeof(byte[])), ForTypeName("boolean", typeof(bool)),
49-
ForTypeName("canonical", typeof(string)), ForTypeName("code", typeof(string)),
50-
ForTypeName("date", typeof(string)), ForTypeName("dateTime", typeof(string)),
51-
ForTypeName("decimal", typeof(decimal)), ForTypeName("id", typeof(string)),
52-
ForTypeName("instant", typeof(DateTimeOffset)), ForTypeName("integer", typeof(int)),
53-
ForTypeName("integer64", typeof(long)), ForTypeName("oid", typeof(string)),
54-
ForTypeName("positiveInt", typeof(int)), ForTypeName("string", typeof(string)),
55-
ForTypeName("time", typeof(string)), ForTypeName("unsignedInt", typeof(int)),
56-
ForTypeName("uri", typeof(string)), ForTypeName("url", typeof(string)),
57-
ForTypeName("xhtml", typeof(string)), ForTypeName("markdown", typeof(string))
81+
Boolean, Base64Binary, Canonical, Code, Date, DateTime, Decimal, Id,
82+
Instant, Integer, Integer64, Oid, PositiveInt, String, Time, UnsignedInt,
83+
Uri, Url, Xhtml, Markdown
5884
];
5985

60-
private static readonly Dictionary<string, PrimitiveTypeReference> s_primitiveDictionary =
86+
private static readonly Dictionary<string, PrimitiveTypeReference> _primitiveDictionary =
6187
PrimitiveList.ToDictionary(ptr => ptr.Name);
6288

63-
public static bool IsFhirPrimitiveType(string name) => s_primitiveDictionary.ContainsKey(name);
89+
public static bool IsFhirPrimitiveType(string name) => _primitiveDictionary.ContainsKey(name);
6490

6591
public static PrimitiveTypeReference GetTypeReference(string name) =>
66-
s_primitiveDictionary.TryGetValue(name, out var tr)
92+
_primitiveDictionary.TryGetValue(name, out var tr)
6793
? tr
6894
: throw new InvalidOperationException($"Unknown FHIR primitive {name}");
6995

@@ -83,10 +109,12 @@ public record CqlTypeReference(string Name, Type PropertyType) : TypeReference(N
83109

84110
public record ComplexTypeReference(string Name, string PocoTypeName) : TypeReference(Name)
85111
{
112+
public ComplexTypeReference(string name) : this(name, name) { }
113+
86114
public override string PropertyTypeString => $"Hl7.Fhir.Model.{PocoTypeName}";
87-
}
88115

89-
public record ChoiceTypeReference() : ComplexTypeReference("DataType", "DataType");
116+
public static readonly ComplexTypeReference DataTypeReference = new("DataType");
117+
}
90118

91119
public record CodedTypeReference(string EnumName, string? EnumClassName)
92120
: PrimitiveTypeReference("code", EnumName, typeof(Enum))

src/Microsoft.Health.Fhir.CodeGen/Microsoft.Health.Fhir.CodeGen.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<PrivateAssets>all</PrivateAssets>
3434
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3535
</PackageReference>
36-
<PackageReference Include="System.Text.Json" Version="8.0.4" />
36+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
3737
</ItemGroup>
3838

3939
<ItemGroup>
@@ -51,5 +51,5 @@
5151
<ItemGroup>
5252
<Folder Include="Polyfill\" />
5353
</ItemGroup>
54-
54+
5555
</Project>

src/Microsoft.Health.Fhir.CodeGenCommon/Extensions/FhirNameConventionExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public static string ToPascalCase(
9595
return string.Join(joinDelimiter, word.Split(delimitersToRemove, _wordSplitOptions).Select(w => w.ToPascalCase(false)));
9696
}
9797

98-
return string.Concat(word.Substring(0, 1).ToUpperInvariant(), word.Substring(1));
98+
return string.Concat(word[..1].ToUpperInvariant(), word[1..]);
9999
}
100100

101101
/// <summary>An extension method that converts an array of words each to PascalCase.</summary>
@@ -163,10 +163,10 @@ public static string ToCamelCase(
163163
{
164164
// converting to pascal and changing the initial letter is faster than accumulating here
165165
string pc = word.ToPascalCase(removeDelimiters, joinDelimiter, delimitersToRemove);
166-
return string.Concat(pc.Substring(0, 1).ToLowerInvariant(), pc.Substring(1));
166+
return string.Concat(pc[..1].ToLowerInvariant(), pc[1..]);
167167
}
168168

169-
return string.Concat(word.Substring(0, 1).ToLowerInvariant(), word.Substring(1));
169+
return string.Concat(word[..1].ToLowerInvariant(), word[1..]);
170170
}
171171

172172
/// <summary>An extension method that converts an array of words each to camelCase.</summary>

src/Microsoft.Health.Fhir.CodeGenCommon/Microsoft.Health.Fhir.CodeGenCommon.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<PrivateAssets>all</PrivateAssets>
1111
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1212
</PackageReference>
13-
<PackageReference Include="System.Text.Json" Version="8.0.4" />
13+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
1414
</ItemGroup>
1515

1616
</Project>

src/Microsoft.Health.Fhir.CrossVersion/Microsoft.Health.Fhir.CrossVersion.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<PrivateAssets>all</PrivateAssets>
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
</PackageReference>
22-
<PackageReference Include="System.Text.Json" Version="8.0.4" />
22+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
2323
</ItemGroup>
2424

2525
<ItemGroup>

src/Microsoft.Health.Fhir.MappingLanguage/Microsoft.Health.Fhir.MappingLanguage.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<PrivateAssets>all</PrivateAssets>
1717
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1818
</PackageReference>
19-
<PackageReference Include="System.Text.Json" Version="8.0.4" />
19+
<PackageReference Include="System.Text.Json" Version="8.0.5" />
2020
</ItemGroup>
2121

2222
<ItemGroup>

0 commit comments

Comments
 (0)