in src/Microsoft.Health.Fhir.Shared.Core/Features/Search/Parameters/SearchParameterToTypeResolver.cs [192:272]
private static EnumerableReturnType Visit(AxisExpression expression, Context ctx)
{
if (ctx.ParentExpression != null)
{
foreach (SearchParameterTypeResult result in Accept(ctx.ParentExpression, ctx.CloneAsChildExpression()))
{
yield return result;
}
}
else
{
var fhirType = ctx.Path.First().propertyName;
var pathBuilder = new StringBuilder(fhirType);
var skipResourceElement = true;
ClassMapping mapping = ctx.Path.First().knownMapping;
if (mapping == null && ModelInfoProvider.Instance.GetTypeForFhirType(fhirType) != null)
{
mapping = GetMapping(fhirType);
}
// Default to parent resource
if (mapping == null)
{
mapping = ctx.ParentTypeMapping;
skipResourceElement = false;
}
foreach ((string, ClassMapping) item in ctx.Path.Skip(skipResourceElement ? 1 : 0))
{
pathBuilder.AppendFormat(".{0}", item.Item1);
if (item.Item2 != null)
{
pathBuilder.AppendFormat("({0})", item.Item2.Name);
mapping = item.Item2;
continue;
}
PropertyMapping prop = mapping.PropertyMappings.FirstOrDefault(x => x.Name == item.Item1);
if (prop != null)
{
if (prop.GetElementType() == typeof(Element) || prop.GetElementType() == typeof(DataType) || prop.Choice == ChoiceType.DatatypeChoice)
{
string path = pathBuilder.ToString();
if (prop.FhirType.Length == 1 && prop.FhirType[0] == typeof(DataType) && prop.Choice == ChoiceType.DatatypeChoice)
{
foreach (var pair in ModelInfo.FhirTypeToCsType)
{
if ((ModelInfo.IsDataType(pair.Value) || ModelInfo.IsPrimitive(pair.Value))
&& !pair.Value.IsAbstract)
{
yield return new SearchParameterTypeResult(GetMapping(pair.Value), ctx.SearchParamType, path, ctx.Definition);
}
}
}
else
{
foreach (Type childFhirType in prop.FhirType)
{
yield return new SearchParameterTypeResult(GetMapping(childFhirType), ctx.SearchParamType, path, ctx.Definition);
}
}
pathBuilder.AppendFormat("({0})", string.Join(",", prop.FhirType.Select(x => x.Name)));
yield break;
}
mapping = GetMapping(prop.GetElementType());
}
else
{
throw new NotSupportedException(string.Format(Core.Resources.CantResolveExpressionForAType, pathBuilder, fhirType));
}
}
yield return new SearchParameterTypeResult(mapping, ctx.SearchParamType, pathBuilder.ToString(), ctx.Definition);
}
}