private Expression Build()

in src/Microsoft.Health.Fhir.Core/Features/Search/Expressions/Parsers/SearchParameterExpressionParser.cs [141:266]


        private Expression Build(
            SearchParameterInfo searchParameter,
            SearchModifier modifier,
            int? componentIndex,
            string value)
        {
            ReadOnlySpan<char> valueSpan = value.AsSpan();

            // By default, the comparator is equal.
            SearchComparator comparator = SearchComparator.Eq;

            if (searchParameter.Type == SearchParamType.Date ||
                searchParameter.Type == SearchParamType.Number ||
                searchParameter.Type == SearchParamType.Quantity)
            {
                // If the search parameter type supports comparator, parse the comparator (if present).
                Tuple<string, SearchComparator> matchedComparator = SearchParamComparators.FirstOrDefault(
                    s => value.StartsWith(s.Item1, StringComparison.Ordinal));

                if (matchedComparator != null)
                {
                    comparator = matchedComparator.Item2;
                    valueSpan = valueSpan.Slice(matchedComparator.Item1.Length);
                }
            }

            // Parse the value.
            Func<string, ISearchValue> parser = _parserDictionary[Enum.Parse<SearchParamType>(searchParameter.Type.ToString())];

            // Build the expression.
            var helper = new SearchValueExpressionBuilderHelper();

            // If the value contains comma, then we need to convert it into in expression.
            // But in this case, the user cannot specify prefix.
            IReadOnlyList<string> parts = value.SplitByOrSeparator();

            if (parts.Count == 1)
            {
                // This is a single value expression.
                ISearchValue searchValue = parser(valueSpan.ToString());
                searchValue = ApplyTargetTypeModifier(modifier, searchValue);

                return helper.Build(
                    searchParameter.Code,
                    modifier,
                    comparator,
                    componentIndex,
                    searchValue);
            }
            else
            {
                if (comparator != SearchComparator.Eq)
                {
                    throw new InvalidSearchOperationException(Resources.SearchComparatorNotSupported);
                }

                // This is a multiple value expression.
                if (modifier?.SearchModifierCode == SearchModifierCode.Not)
                {
                    Expression[] expressions = parts.Select(part =>
                    {
                        ISearchValue searchValue = parser(part);

                        return helper.Build(
                            searchParameter.Code,
                            null,
                            comparator,
                            componentIndex,
                            searchValue);
                    }).ToArray();

                    return Expression.Not(Expression.Or(expressions));
                }
                else
                {
                    Expression[] expressions = parts.Select(part =>
                    {
                        ISearchValue searchValue = parser(part);
                        searchValue = ApplyTargetTypeModifier(modifier, searchValue);

                        return helper.Build(
                            searchParameter.Code,
                            modifier,
                            comparator,
                            componentIndex,
                            searchValue);
                    }).ToArray();

                    return Expression.Or(expressions);
                }
            }

            ISearchValue ApplyTargetTypeModifier(SearchModifier modifier, ISearchValue source)
            {
                var referenceSearchValue = source as ReferenceSearchValue;
                if (referenceSearchValue == null || modifier?.SearchModifierCode != SearchModifierCode.Type)
                {
                    return source;
                }

                if (!string.IsNullOrEmpty(referenceSearchValue.ResourceType))
                {
                    if (string.Equals(referenceSearchValue.ResourceType, modifier.ResourceType, StringComparison.OrdinalIgnoreCase))
                    {
                        return source;
                    }

                    throw new InvalidSearchOperationException(
                        string.Format(Core.Resources.ModifierNotSupported, modifier, searchParameter.Code));
                }

                try
                {
                    return new ReferenceSearchValue(
                        referenceSearchValue.Kind,
                        referenceSearchValue.BaseUri,
                        modifier.ResourceType,
                        referenceSearchValue.ResourceId);
                }
                catch (ArgumentException)
                {
                    throw new InvalidSearchOperationException(
                        string.Format(Core.Resources.ModifierNotSupported, modifier, searchParameter.Code));
                }
            }
        }