public async Task <CompletionContext> GetCompletionContextAsync(
            IAsyncCompletionSession session,
            CompletionTrigger trigger,
            SnapshotPoint triggerLocation,
            SnapshotSpan applicableSpan,
            CancellationToken token)
        {
            try
            {
                var codeDocument = await Parser.GetLatestCodeDocumentAsync(triggerLocation.Snapshot, token);

                if (codeDocument is null)
                {
                    return(CompletionContext.Empty);
                }

                var location   = new SourceSpan(triggerLocation.Position, 0);
                var syntaxTree = codeDocument.GetSyntaxTree();
                var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
                var razorCompletionContext   = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);
                var razorCompletionItems     = _completionFactsService.GetCompletionItems(razorCompletionContext, location);

                var completionItems = new List <CompletionItem>();
                foreach (var razorCompletionItem in razorCompletionItems)
                {
                    if (razorCompletionItem.Kind != RazorCompletionItemKind.Directive)
                    {
                        // Don't support any other types of completion kinds other than directives.
                        continue;
                    }

                    var completionItem = new CompletionItem(
                        displayText: razorCompletionItem.DisplayText,
                        filterText: razorCompletionItem.DisplayText,
                        insertText: razorCompletionItem.InsertText,
                        source: this,
                        icon: DirectiveImageGlyph,
                        filters: DirectiveCompletionFilters,
                        suffix: string.Empty,
                        sortText: razorCompletionItem.DisplayText,
                        attributeIcons: ImmutableArray <ImageElement> .Empty);
                    var completionDescription = razorCompletionItem.GetDirectiveCompletionDescription();
                    completionItem.Properties.AddProperty(DescriptionKey, completionDescription);
                    completionItems.Add(completionItem);
                }

                var context = new CompletionContext(completionItems.ToImmutableArray());
                return(context);
            }
            catch (OperationCanceledException)
            {
                return(CompletionContext.Empty);
            }
        }
        public async Task <CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession session, CompletionTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            try
            {
                var codeDocument = await _parser.GetLatestCodeDocumentAsync(triggerLocation.Snapshot, token);

                if (codeDocument == null)
                {
                    // Code document not available yet.
                    return(CompletionContext.Empty);
                }

                var syntaxTree = codeDocument.GetSyntaxTree();
                var tagHelperDocumentContext = codeDocument.GetTagHelperContext();
                var location = new SourceSpan(triggerLocation.Position, 0);

                var razorCompletionContext = new RazorCompletionContext(syntaxTree, tagHelperDocumentContext);
                var razorCompletionItems   = _completionFactsService.GetCompletionItems(razorCompletionContext, location);

                if (razorCompletionItems.Count == 0)
                {
                    return(CompletionContext.Empty);
                }

                // Check if we're providing completion items while a legacy completion session is active. If so
                // we'll need to dismiss the legacy completion session to ensure we don't get two completion lists.
                var activeSessions = _completionBroker.GetSessions(session.TextView);
                foreach (var activeSession in activeSessions)
                {
                    if (activeSession.Properties.ContainsProperty(nameof(IAsyncCompletionSession)))
                    {
                        continue;
                    }

                    // Legacy completion is also active, we need to dismiss it.

                    await _joinableTaskFactory.SwitchToMainThreadAsync();

                    activeSession.Dismiss();
                }

                var completionItems     = new List <CompletionItem>();
                var completionItemKinds = new HashSet <RazorCompletionItemKind>();
                foreach (var razorCompletionItem in razorCompletionItems)
                {
                    if (razorCompletionItem.Kind != RazorCompletionItemKind.DirectiveAttribute &&
                        razorCompletionItem.Kind != RazorCompletionItemKind.DirectiveAttributeParameter)
                    {
                        // Don't support any other types of completion kinds other than directive attributes and their parameters.
                        continue;
                    }

                    var completionItem = new CompletionItem(
                        displayText: razorCompletionItem.DisplayText,
                        filterText: razorCompletionItem.DisplayText,
                        insertText: razorCompletionItem.InsertText,
                        source: this,
                        icon: s_directiveAttributeImageGlyph,
                        filters: s_directiveAttributeCompletionFilters,
                        suffix: string.Empty,
                        sortText: razorCompletionItem.DisplayText,
                        attributeIcons: ImmutableArray <ImageElement> .Empty);
                    completionItems.Add(completionItem);
                    completionItemKinds.Add(razorCompletionItem.Kind);

                    var completionDescription = razorCompletionItem.GetAttributeCompletionDescription();
                    completionItem.Properties[DescriptionKey] = completionDescription;
                }

                session.Properties.SetCompletionItemKinds(completionItemKinds);
                var orderedCompletionItems = completionItems.OrderBy(item => item.DisplayText);
                var context = new CompletionContext(orderedCompletionItems.ToImmutableArray());
                return(context);
            }
            catch (OperationCanceledException)
            {
                return(CompletionContext.Empty);
            }
        }