private static CodeTypeReference CreateTypeReference(ITypedElement typedElement, System.Action<CodeAttributeDeclaration> attributePersistor, System.Func<ITypedElement, CodeTypeReference, ITransformationContext, CodeTypeReference> getCollectionType, ITransformationContext context)
 {
     if (typedElement == null) return new CodeTypeReference(typeof(void));
     CodeTypeReference elementType;
     var systemType = typedElement.Type as IPrimitiveType;
     if (systemType != null)
     {
         elementType = new CodeTypeReference(systemType.SystemType);
     }
     else
     {
         var type = typedElement.Type;
         bool isReference;
         if (type != null)
         {
             isReference = type is IReferenceType;
         }
         else
         {
             isReference = typedElement is IReference;
         }
         elementType = CreateReference(typedElement.Type, isReference, context);
     }
     if (typedElement.UpperBound == 1)
     {
         return elementType;
     }
     else
     {
         if (attributePersistor != null)
         {
             if (typedElement.LowerBound > 0) attributePersistor(new CodeAttributeDeclaration(new CodeTypeReference(typeof(LowerBoundAttribute).Name), new CodeAttributeArgument(new CodePrimitiveExpression(typedElement.LowerBound))));
             if (typedElement.UpperBound > 1) attributePersistor(new CodeAttributeDeclaration(new CodeTypeReference(typeof(UpperBoundAttribute).Name), new CodeAttributeArgument(new CodePrimitiveExpression(typedElement.UpperBound))));
         }
         if (getCollectionType == null)
         {
             return new CodeTypeReference(typeof(IEnumerable<>).Name, elementType);
         }
         else
         {
             return getCollectionType(typedElement, elementType, context);
         }
     }
 }
 public static void VisitAll(this ITypedElement nav) => nav.Visit((_, n) => { var dummy = n.Value; });
 public static void Visit(this ITypedElement root, Action <int, ITypedElement> visitor) => root.visit(visitor, 0);
 /// <summary>
 ///     Provides the statement which modifies the variable
 /// </summary>
 /// <param name="variable"></param>
 /// <returns>null if no statement modifies the element</returns>
 public abstract VariableUpdateStatement Modifies(ITypedElement variable);
        public bool Reads(ITypedElement variable)
        {
            bool retVal = false;

            foreach (Case cas in Cases)
            {
                if (cas.Read(variable))
                {
                    retVal = true;
                    break;
                }
            }

            return retVal;
        }
        /// <summary>
        ///     Indicates whether this statement reads the element
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public override bool Reads(ITypedElement variable)
        {
            foreach (Action action in Actions)
            {
                if (action.Reads(variable))
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Provides the mode for the typed element provided
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public Usage.ModeEnum GetModeForTypedElement(ITypedElement element)
        {
            Usage.ModeEnum retVal = Usage.ModeEnum.Read;

            foreach (Action action in Actions)
            {
                Usage.ModeEnum mode = action.GetModeForTypedElement(element);
                if (mode != Usage.ModeEnum.Read)
                {
                    retVal = mode;
                    break;
                }
            }

            return retVal;
        }
Exemple #8
0
        /// <summary>
        ///     Indicates whether this call may read a given variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public bool Reads(ITypedElement variable)
        {
            bool retVal = false;

            Function function = Called.getStaticCallable() as Function;
            if (function != null)
            {
                retVal = function.Reads(variable);
            }

            return retVal;
        }
        public static bool IsEqualTo(this ITypedElement left, ITypedElement right, bool compareNames = false)
        {
            if (compareNames && (left.Name != right.Name))
            {
                return(false);
            }

            var l = left.Value;
            var r = right.Value;

            // Compare primitives (or extended primitives)
            if (l != null && r != null)
            {
                if (l.GetType() == typeof(string) && r.GetType() == typeof(string))
                {
                    return((string)l == (string)r);
                }
                else if (l.GetType() == typeof(bool) && r.GetType() == typeof(bool))
                {
                    return((bool)l == (bool)r);
                }
                else if (l.GetType() == typeof(long) && r.GetType() == typeof(long))
                {
                    return((long)l == (long)r);
                }
                else if (l.GetType() == typeof(decimal) && r.GetType() == typeof(decimal))
                {
                    return((decimal)l == (decimal)r);
                }
                else if (l.GetType() == typeof(long) && r.GetType() == typeof(decimal))
                {
                    return((decimal)(long)l == (decimal)r);
                }
                else if (l.GetType() == typeof(decimal) && r.GetType() == typeof(long))
                {
                    return((decimal)l == (decimal)(long)r);
                }
                else if (l.GetType() == typeof(PartialTime) && r.GetType() == typeof(PartialTime))
                {
                    return((PartialTime)l == (PartialTime)r);
                }
                else if (l.GetType() == typeof(PartialDateTime) && r.GetType() == typeof(PartialDateTime))
                {
                    return((PartialDateTime)l == (PartialDateTime)r);
                }
                else
                {
                    return(false);
                }
            }
            else if (l == null && r == null)
            {
                // Compare complex types (extensions on primitives are not compared, but handled (=ignored) above
                var childrenL = left.Children();
                var childrenR = right.Children();

                return(childrenL.IsEqualTo(childrenR, compareNames: true));    // NOTE: Assumes null will never be returned when any() children exist
            }
            else
            {
                // Else, we're comparing a complex (without a value) to a primitive which (probably) should return false
                return(false);
            }
        }
Exemple #10
0
#pragma warning restore 612, 618

        public static byte[] ToXmlBytes(this ITypedElement source, FhirXmlSerializationSettings settings = null)
        => SerializationUtil.WriteXmlToBytes(writer => source.WriteTo(writer, settings));
Exemple #11
0
 public static string ToXml(this ITypedElement source, FhirXmlSerializationSettings settings = null)
 => SerializationUtil.WriteXmlToString(writer => source.WriteTo(writer, settings), settings?.Pretty ?? false, settings?.AppendNewLine ?? false);
Exemple #12
0
 public static XDocument ToXDocument(this ITypedElement source, FhirXmlSerializationSettings settings = null) =>
 new FhirXmlBuilder(settings).Build(source);
 /// <summary>
 ///     Considers the type of the element provided as parameter
 /// </summary>
 /// <param name="element">The element which uses this type</param>
 private void ConsiderTypeOfElement(ITypedElement element)
 {
     ModelElement modelElement = element as ModelElement;
     if (modelElement != null)
     {
         if (Model != null)
         {
             if ((element.Type == Model) && (element != Model))
             {
                 Usages.Add(new Usage(Model, modelElement, Usage.ModeEnum.Type));
             }
         }
         else
         {
             if (Filter.AcceptableChoice(element.Type))
             {
                 Usages.Add(new Usage(element.Type, modelElement, Usage.ModeEnum.Type));
             }
         }
     }
 }
        /// <summary>
        /// Provides the mode for the typed element provided
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public Usage.ModeEnum GetModeForTypedElement(ITypedElement element)
        {
            Usage.ModeEnum retVal = Usage.ModeEnum.Read;

            ReferenceVisitor visitor = new ReferenceVisitor(element);
            visitor.ConsiderInterpreterTreeNode(Statement);
            foreach (Usage usage in visitor.Usages)
            {
                if (usage.Mode != null && usage.Mode != Usage.ModeEnum.Read)
                {
                    retVal = (Usage.ModeEnum) usage.Mode;
                    break;
                }
            }

            return retVal;
        }
        protected void InsertElement(ITypedElement element, TextualExplanation text)
        {
            text.Write(element.Name);
            text.Write(" => ");
            Structure structure = element.Type as Structure;
            if (structure != null)
            {
                text.WriteLine(StripUseless(structure.FullName, WritingContext()) + "{");
                text.Indent(4, () =>
                {
                    bool first = true;
                    foreach (StructureElement subElement in structure.Elements)
                    {
                        if (!first)
                        {
                            text.WriteLine(",");
                        }
                        InsertElement(subElement, text);
                        first = false;
                    }
                });
                text.WriteLine();
                text.Write("}");
            }
            else
            {
                IValue value = null;
                if (string.IsNullOrEmpty(element.Default))
                {
                    // No default value for element, get the one of the type
                    if (element.Type != null && element.Type.DefaultValue != null)
                    {
                        value = element.Type.DefaultValue;
                    }
                }
                else
                {
                    if (element.Type != null)
                    {
                        value = element.Type.getValue(element.Default);
                    }
                }

                if (value != null)
                {
                    text.Write(StripUseless(value.FullName, WritingContext()));
                }
            }
        }
 public PrimitiveValueReader(ITypedElement data)
 {
     _current   = data;
     _inspector = BaseFhirParser.Inspector;
 }
 public static MaskingNode ForSummary(ITypedElement node) =>
 new MaskingNode(node, new MaskingNodeSettings
 {
     IncludeInSummary = true,
     PreserveBundle   = MaskingNodeSettings.PreserveBundleMode.Root
 });
Exemple #18
0
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
                                        bool apply, Runner runner)
        {
            if (Call != null)
            {
                // Explain what happens in this statement
                explanation = ExplanationPart.CreateSubExplanation(explanation, this);

                InterpretationContext ctxt      = GetContext(context, explanation);
                Procedure             procedure = Call.GetProcedure(ctxt, explanation);
                if (procedure != null)
                {
                    ctxt.HasSideEffects = true;

                    // If the procedure has been defined in a structure,
                    // ensure that it is applied to an instance of that structure
                    Structure structure = procedure.Enclosing as Structure;
                    if (structure != null)
                    {
                        ITypedElement current = ctxt.Instance as ITypedElement;
                        while (current != null)
                        {
                            if (current.Type != structure)
                            {
                                current = current.Enclosing as ITypedElement;
                            }
                            else
                            {
                                ctxt.Instance = current;
                                ExplanationPart.CreateSubExplanation(explanation, "Instance", current);

                                current = null;
                            }
                        }
                    }

                    ExplanationPart part = ExplanationPart.CreateSubExplanation(explanation, procedure);
                    if (ctxt.Instance is IVariable)
                    {
                        ExplanationPart.SetNamable(part, ctxt.Instance);
                        ExplanationPart instanceExplanation = ExplanationPart.CreateSubExplanation(part, "instance = ");
                        ExplanationPart.SetNamable(instanceExplanation, ctxt.Instance);
                    }

                    int token = ctxt.LocalScope.PushContext();
                    foreach (
                        KeyValuePair <Actual, IValue> pair in Call.AssignParameterValues(context, procedure, true, part))
                    {
                        ctxt.LocalScope.SetVariable(pair.Key, pair.Value);
                    }

                    foreach (Rule rule in procedure.Rules)
                    {
                        ApplyRule(rule, changes, ctxt, part, runner);
                    }

                    ctxt.LocalScope.PopContext(token);
                }
                else
                {
                    AddError("Cannot determine the called procedure for " + ToString(), RuleChecksEnum.ExecutionFailed);
                }
            }
            else
            {
                AddError("Expression " + ToString() + " is not a valid procedure call", RuleChecksEnum.ExecutionFailed);
            }
        }
 /// <summary>
 ///     Considers the type of the element provided as parameter
 /// </summary>
 /// <param name="element">The element which uses this type</param>
 private void ConsiderTypeOfElement(ITypedElement element)
 {
     ModelElement modelElement = element as ModelElement;
     if (modelElement != null)
     {
         Type current = element.Type;
         while (current != null)
         {
             if (Model != null)
             {
                 if ((current == Model) && (element != Model))
                 {
                     Usages.Add(new Usage(Model, modelElement, Usage.ModeEnum.Type));
                 }
             }
             else
             {
                 if (Filter.AcceptableChoice(current))
                 {
                     Usages.Add(new Usage(element.Type, modelElement, Usage.ModeEnum.Type));
                 }
             }
             current = EnclosingFinder<Type>.find(current);
         }
     }
 }
Exemple #20
0
 public FhirEvaluationContext(ITypedElement context) : base(context)
 {
 }
        /// <summary>
        ///     Provides the statement which modifies the element
        /// </summary>
        /// <param name="variable"></param>
        /// <returns>null if no statement modifies the element</returns>
        public override VariableUpdateStatement Modifies(ITypedElement variable)
        {
            VariableUpdateStatement retVal = null;

            if (variable == Target)
            {
                retVal = this;
            }

            return retVal;
        }
Exemple #22
0
 internal ResourceElement(ITypedElement instance, object resourceInstance)
     : this(instance)
 {
     EnsureArg.IsNotNull(resourceInstance, nameof(resourceInstance));
     ResourceInstance = resourceInstance;
 }
        /// <summary>
        ///     Indicates whether this rule reads the content of this variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public bool Reads(ITypedElement variable)
        {
            foreach (PreCondition precondition in PreConditions)
            {
                if (precondition.Reads(variable))
                {
                    return true;
                }
            }

            foreach (Action action in Actions)
            {
                if (action.Reads(variable))
                {
                    return true;
                }
            }

            return false;
        }
Exemple #24
0
 internal BubbledChangeEventArgs(IModelElement element, ITypedElement feature = null)
 {
     Element = element;
     Feature = feature;
 }
        /// <summary>
        ///     Indicates whether this action reads the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public bool Reads(ITypedElement variable)
        {
            if (Statement != null)
            {
                return Statement.Reads(variable);
            }

            return false;
        }
Exemple #26
0
 public static T ParsePrimitive <T>(this ITypedElement instance) where T : Primitive, new()
 => new T()
 {
     ObjectValue = instance.Value
 };
Exemple #27
0
 public static Base ToPoco(this ITypedElement element, PocoBuilderSettings settings = null) =>
 new PocoBuilder(settings).BuildFrom(element);
Exemple #28
0
 public static T ToPoco <T>(this ITypedElement element, PocoBuilderSettings settings = null) where T : Base =>
 (T)element.ToPoco(settings);
 public static IDisposable Catch(this ITypedElement source, ExceptionNotificationHandler handler) =>
 source is IExceptionSource s?s.Catch(handler) : throw new NotImplementedException("Element does not implement IExceptionSource.");
Exemple #30
0
        public IList <Bug.Common.Dto.Indexing.IndexUri> Set(Bug.Common.Enums.FhirVersion fhirVersion, ITypedElement typedElement, Bug.Common.Enums.ResourceType resourceType, int searchParameterId, string searchParameterName)
        {
            switch (fhirVersion)
            {
            case Common.Enums.FhirVersion.Stu3:
                var Stu3Tool = IFhirIndexUriSetterSupportFactory.GetStu3();
                return(Stu3Tool.Set(typedElement, resourceType, searchParameterId, searchParameterName));

            case Common.Enums.FhirVersion.R4:
                var R4Tool = IFhirIndexUriSetterSupportFactory.GetR4();
                return(R4Tool.Set(typedElement, resourceType, searchParameterId, searchParameterName));

            default:
                throw new FhirVersionFatalException(fhirVersion);
            }
        }
 public static IEnumerable <object> Annotations(this ITypedElement nav, Type type) =>
 nav is IAnnotated ann?ann.Annotations(type) : Enumerable.Empty <object>();
Exemple #32
0
 private TypedElementToSourceNodeAdapter(TypedElementToSourceNodeAdapter parent, ITypedElement child)
 {
     Current          = child;
     ExceptionHandler = parent.ExceptionHandler;
 }
        private (bool included, bool mandatory) included(ITypedElement node)
        {
            var scope = getScope(node);

            // Trivially, we will include the root
            if (!scope.Location.Contains("."))
            {
                return(true, false);
            }

            bool atRootBundle() => atBundle() && scope.ParentResource == null;
            bool atBundle() => scope.NearestResourceType == "Bundle";

            switch (_settings.PreserveBundle)
            {
            case MaskingNodeSettings.PreserveBundleMode.All when atBundle():
            case MaskingNodeSettings.PreserveBundleMode.Root when atRootBundle():
                return(true, false);

                // fall through...
            }

            var included = _settings.IncludeAll || _includeAll;

            bool mandatory = false;         // included because it's required & includeMandatory is on
            var  ed        = scope.Definition;

            if (ed != null)
            {
                mandatory = _settings.IncludeMandatory && ed.IsRequired;
                included |= mandatory;
                included |= _settings.IncludeInSummary && ed.InSummary;
            }

            var loc     = scope.LocalLocation;
            var nearest = scope.NearestResourceType;

            included |= _settings.IncludeElements?.Any(matches) ?? false;

            if (_settings.ExcludeElements?.Any(matches) == true)
            {
                return(false, false);
            }

            bool matches(string filter)
            {
                var f = nearest + "." + filter;

                return(loc == f || loc.StartsWith(f + ".") || loc.StartsWith(f + "["));    // include matches + children
            }

            if (_settings.ExcludeMarkdown && scope.InstanceType == "markdown")
            {
                return(false, false);
            }
            if (_settings.ExcludeNarrative & scope.InstanceType == "Narrative")
            {
                return(false, false);
            }

            return(included, mandatory);
        }
 static ITypedElement resolver(ITypedElement f, EvaluationContext ctx)
 {
     return(ctx is FhirEvaluationContext fctx?f.Resolve(fctx.ElementResolver) : f.Resolve());
 }
        /// <summary>
        ///     Refactors an element which has a type
        /// </summary>
        /// <param name="element">The element that has been modified</param>
        /// <param name="user">The user which references this type</param>
        private static void RefactorTypedElement(ModelElement element, ITypedElement user)
        {
            if (user != null)
            {
                try
                {
                    ModelElement enclosing = EnclosingFinder<NameSpace>.find(user, true);

                    Function function = user as Function;
                    if (function != null)
                    {
                        bool refactor = false;
                        Type current = function.ReturnType;
                        while (current != null && !refactor)
                        {
                            refactor = current == element;
                            current = EnclosingFinder<Type>.find(current);
                        }

                        if (refactor)
                        {
                            function.TypeName = function.ReturnType.ReferenceName(enclosing);
                        }
                    }
                    else
                    {
                        bool refactor = false;
                        Type current = user.Type;
                        while (current != null && !refactor)
                        {
                            refactor = current == element;
                            current = EnclosingFinder<Type>.find(current);
                        }

                        if (refactor)
                        {
                            user.TypeName = user.Type.ReferenceName(enclosing);
                        }
                    }
                }
                catch (Exception e)
                {
                    ((ModelElement)user).AddError("Cannot refactor this element, reason = " + e.Message);
                }
            }
        }
 public void DeleteSearchParameter(ITypedElement searchParam)
 {
     _inner.DeleteSearchParameter(searchParam);
 }
Exemple #37
0
        public bool Read(ITypedElement variable)
        {
            bool retVal = false;

            foreach (PreCondition preCondition in PreConditions)
            {
                if (preCondition.Reads(variable))
                {
                    retVal = true;
                    break;
                }
            }

            if (!retVal && Expression != null)
            {
                foreach (IVariable var in Expression.GetVariables())
                {
                    if (var == variable)
                    {
                        retVal = true;
                        break;
                    }
                }
            }

            return retVal;
        }
 public static bool Contains(this IEnumerable <ITypedElement> focus, ITypedElement value)
 {
     return(focus.Contains(value, new EqualityOperators.ValueProviderEqualityComparer()));
 }
        /// <summary>
        ///     Provides the statement which modifies the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns>null if no statement modifies the element</returns>
        public override VariableUpdateStatement Modifies(ITypedElement variable)
        {
            VariableUpdateStatement retVal = AppliedStatement.Modifies(variable);

            return retVal;
        }
Exemple #40
0
        private static CompiledExpression getExecutableConstraint(Validator v, OperationOutcome outcome, ITypedElement instance,
                                                                  ElementDefinition.ConstraintComponent constraintElement)
        {
            var compiledExpression = constraintElement.Annotation <CompiledConstraintAnnotation>()?.Expression;

            if (compiledExpression == null)
            {
                var fpExpressionText = constraintElement.GetFhirPathConstraint();

                if (fpExpressionText != null)
                {
                    try
                    {
                        compiledExpression = v.FpCompiler.Compile(fpExpressionText);
                        constraintElement.AddAnnotation(new CompiledConstraintAnnotation {
                            Expression = compiledExpression
                        });
                    }
                    catch (Exception e)
                    {
                        v.Trace(outcome, $"Compilation of FhirPath for constraint '{constraintElement.Key}' failed: {e.Message}",
                                Issue.PROFILE_ELEMENTDEF_INVALID_FHIRPATH_EXPRESSION, instance);
                    }
                }
                else
                {
                    v.Trace(outcome, $"Encountered an invariant ({constraintElement.Key}) that has no FhirPath expression, skipping validation of this constraint",
                            Issue.UNSUPPORTED_CONSTRAINT_WITHOUT_FHIRPATH, instance);
                }
            }

            return(compiledExpression);
        }
        /// <summary>
        ///     Provides the statement which modifies the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns>null if no statement modifies the element</returns>
        public override VariableUpdateStatement Modifies(ITypedElement variable)
        {
            VariableUpdateStatement retVal = null;

            return retVal;
        }
 public EvaluationContext GetEvaluationContext(ITypedElement element)
 {
     return(new FhirEvaluationContext(element));
 }
        /// <summary>
        ///     Indicates whether this statement reads the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public virtual bool Reads(ITypedElement variable)
        {
            List<ITypedElement> variablesRead = new List<ITypedElement>();
            ReadElements(variablesRead);

            return variablesRead.Contains(variable);
        }
 /// <summary>
 ///     Provides the statement which modifies the element
 /// </summary>
 /// <param name="element"></param>
 /// <returns>null if no statement modifies the element</returns>
 public override VariableUpdateStatement Modifies(ITypedElement element)
 {
     return(null);
 }
        /// <summary>
        ///     Provides the statement which modifies the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns>null if no statement modifies the element</returns>
        public VariableUpdateStatement Modifies(ITypedElement variable)
        {
            VariableUpdateStatement retVal = null;

            foreach (Action action in Actions)
            {
                retVal = action.Modifies(variable);
                if (retVal != null)
                {
                    return retVal;
                }
            }

            return retVal;
        }
        private IEnumerable <SearchIndexEntry> ProcessNonCompositeSearchParameter(SearchParameterInfo searchParameter, ITypedElement resource, EvaluationContext context)
        {
            EnsureArg.IsNotNull(searchParameter, nameof(searchParameter));
            Debug.Assert(searchParameter.Type != SearchParamType.Composite, "The search parameter must be non-composite.");

            SearchParameterInfo searchParameterInfo = searchParameter;

            foreach (ISearchValue searchValue in ExtractSearchValues(
                         searchParameter.Url.ToString(),
                         searchParameter.Type,
                         searchParameter.TargetResourceTypes,
                         resource,
                         searchParameter.Expression,
                         context))
            {
                yield return(new SearchIndexEntry(searchParameterInfo, searchValue));
            }
        }
        /// <summary>
        ///     Indicates whether this preCondition reads the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public bool Reads(ITypedElement variable)
        {
            bool retVal = false;

            if (Expression != null)
            {
                foreach (ITypedElement el in Expression.GetVariables())
                {
                    if (el == variable)
                    {
                        retVal = true;
                        break;
                    }
                }

                if (!retVal)
                {
                    Call call = Expression as Call;
                    if (call != null)
                    {
                        retVal = call.Reads(variable);
                    }
                }
            }

            return retVal;
        }
        private IReadOnlyList <ISearchValue> ExtractSearchValues(
            string searchParameterDefinitionUrl,
            SearchParamType?searchParameterType,
            IReadOnlyList <string> allowedReferenceResourceTypes,
            ITypedElement element,
            string fhirPathExpression,
            EvaluationContext context)
        {
            Debug.Assert(searchParameterType != SearchParamType.Composite, "The search parameter must be non-composite.");

            var results = new List <ISearchValue>();

            // For simple value type, we can parse the expression directly.
            IEnumerable <ITypedElement> extractedValues = Enumerable.Empty <ITypedElement>();

            try
            {
                extractedValues = element.Select(fhirPathExpression, context);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(
                    ex,
                    "Failed to extract the values using '{FhirPathExpression}' against '{ElementType}'.",
                    fhirPathExpression,
                    element.GetType());
            }

            Debug.Assert(extractedValues != null, "The extracted values should not be null.");

            // If there is target set, then filter the extracted values to only those types.
            if (searchParameterType == SearchParamType.Reference &&
                allowedReferenceResourceTypes?.Count > 0)
            {
                List <string> targetResourceTypes = _targetTypesLookup.GetOrAdd(searchParameterDefinitionUrl, _ =>
                {
                    return(allowedReferenceResourceTypes.Select(t => t.ToString()).ToList());
                });

                // TODO: The expression for reference search parameters in STU3 has issues.
                // The reference search parameter could be pointing to an element that can be multiple types. For example,
                // the Appointment.participant.actor can be type of Patient, Practitioner, Related Person, Location, and so on.
                // Some search parameter could refer to this property but restrict to certain types. For example,
                // Appointment's location search parameter is returned only when Appointment.participant.actor is Location element.
                // The STU3 expressions don't have this restriction so everything is being returned. This is addressed in R4 release (see
                // http://community.fhir.org/t/expression-seems-incorrect-for-reference-search-parameter-thats-only-applicable-to-certain-types/916/2).
                // Therefore, for now, we will need to compare the reference value itself (which can be internal or external references), and restrict
                // the values ourselves.
                extractedValues = extractedValues.Where(ev =>
                {
                    if (ev.InstanceType.Equals("ResourceReference", StringComparison.OrdinalIgnoreCase))
                    {
                        var rr = ev.Scalar("reference") as string;
                        return(rr != null && targetResourceTypes.Any(trt => rr.Contains(trt, StringComparison.Ordinal)));
                    }

                    return(true);
                });
            }

            foreach (var extractedValue in extractedValues)
            {
                if (!_fhirElementTypeConverterManager.TryGetConverter(extractedValue.InstanceType, GetSearchValueTypeForSearchParamType(searchParameterType), out IFhirNodeToSearchValueTypeConverter converter))
                {
                    _logger.LogWarning(
                        "The FHIR element '{ElementType}' is not supported.",
                        extractedValue.InstanceType);

                    continue;
                }

                IEnumerable <ISearchValue> searchValues = converter.ConvertTo(extractedValue);

                if (searchValues != null)
                {
                    if (searchParameterType == SearchParamType.Reference && allowedReferenceResourceTypes?.Count == 1)
                    {
                        // For references, if the type is not specified in the reference string, we can set the type on the search value because
                        // in this case it can only be of one type.
                        string singleAllowedResourceType = allowedReferenceResourceTypes[0];
                        foreach (ISearchValue searchValue in searchValues)
                        {
                            if (searchValue is ReferenceSearchValue rsr && string.IsNullOrEmpty(rsr.ResourceType))
                            {
                                results.Add(new ReferenceSearchValue(rsr.Kind, rsr.BaseUri, singleAllowedResourceType, rsr.ResourceId));
                            }
                            else
                            {
                                results.Add(searchValue);
                            }
                        }
                    }
        /// <summary>
        ///     Provides the statement which modifies the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns>null if no statement modifies the element</returns>
        public VariableUpdateStatement Modifies(ITypedElement variable)
        {
            if (Statement != null)
            {
                return Statement.Modifies(variable);
            }

            return null;
        }
        private IEnumerable <SearchIndexEntry> ProcessCompositeSearchParameter(SearchParameterInfo searchParameter, ITypedElement resource, EvaluationContext context)
        {
            Debug.Assert(searchParameter?.Type == SearchParamType.Composite, "The search parameter must be composite.");

            SearchParameterInfo compositeSearchParameterInfo = searchParameter;

            IEnumerable <ITypedElement> rootObjects = resource.Select(searchParameter.Expression, context);

            foreach (var rootObject in rootObjects)
            {
                int  numberOfComponents = searchParameter.Component.Count;
                bool skip = false;

                var componentValues = new IReadOnlyList <ISearchValue> [numberOfComponents];

                // For each object extracted from the expression, we will need to evaluate each component.
                for (int i = 0; i < numberOfComponents; i++)
                {
                    SearchParameterComponentInfo component = searchParameter.Component[i];

                    // First find the type of the component.
                    SearchParameterInfo componentSearchParameterDefinition = searchParameter.Component[i].ResolvedSearchParameter;

                    IReadOnlyList <ISearchValue> extractedComponentValues = ExtractSearchValues(
                        componentSearchParameterDefinition.Url.ToString(),
                        componentSearchParameterDefinition.Type,
                        componentSearchParameterDefinition.TargetResourceTypes,
                        rootObject,
                        component.Expression,
                        context);

                    // Filter out any search value that's not valid as a composite component.
                    extractedComponentValues = extractedComponentValues
                                               .Where(sv => sv.IsValidAsCompositeComponent)
                                               .ToArray();

                    if (!extractedComponentValues.Any())
                    {
                        // One of the components didn't have any value and therefore it will not be indexed.
                        skip = true;
                        break;
                    }

                    componentValues[i] = extractedComponentValues;
                }

                if (skip)
                {
                    continue;
                }

                yield return(new SearchIndexEntry(compositeSearchParameterInfo, new CompositeSearchValue(componentValues)));
            }
        }
 /// <summary>
 ///     Provides the statement which modifies the element
 /// </summary>
 /// <param name="element"></param>
 /// <returns>null if no statement modifies the element</returns>
 public override VariableUpdateStatement Modifies(ITypedElement element)
 {
     return null;
 }
 public static IEnumerable <ITypedElement> DescendantsAndSelf(this ITypedElement element) =>
 (new[] { element }).Concat(element.Descendants());
        /// <summary>
        ///     Indicates whether this statement reads the variable
        /// </summary>
        /// <param name="variable"></param>
        /// <returns></returns>
        public virtual bool Reads(ITypedElement variable)
        {
            bool retVal = false;

            List<ITypedElement> variablesRead = new List<ITypedElement>();
            ReadElements(variablesRead);
            retVal = variablesRead.Contains(variable);

            return retVal;
        }
 /// <summary>
 ///     Refactors an element which has a type
 /// </summary>
 /// <param name="element">The element that has been modified</param>
 /// <param name="user">The user which references this type</param>
 private static void RefactorTypedElement(ModelElement element, ITypedElement user)
 {
     if (user != null)
     {
         ModelElement enclosing = EnclosingFinder<NameSpace>.find(user, true);
         try
         {
             Function userFunction = user as Function;
             if ((user.Type == element))
             {
                 string newName = element.ReferenceName(enclosing);
                 user.TypeName = newName;
             }
             else if (userFunction != null && userFunction.ReturnType == element)
             {
                 userFunction.ReturnType = element as Type;
             }
             else if (element is NameSpace)
             {
                 string newName;
                 Function function = user as Function;
                 if (function != null)
                 {
                     newName = function.ReturnType.ReferenceName(user as ModelElement);
                     user.TypeName = newName;
                 }
                 else
                 {
                     newName = user.Type.ReferenceName(user as ModelElement);
                     user.TypeName = newName;
                 }
             }
         }
         catch (Exception e)
         {
             ((ModelElement) user).AddError("Cannot refactor this element, reason = " + e.Message);
         }
     }
 }