internal async Task <(RegexTree tree, SyntaxToken token)> TryGetTreeAndTokenAtPositionAsync(
            Document document, int position, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var token       = root.FindToken(position);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            if (RegexPatternDetector.IsDefinitelyNotPattern(token, syntaxFacts))
            {
                return(default);
        public override void AddClassifications(
            Workspace workspace, SyntaxToken token, SemanticModel semanticModel,
            ArrayBuilder <ClassifiedSpan> result, CancellationToken cancellationToken)
        {
            if (_info.StringLiteralTokenKind != token.RawKind)
            {
                return;
            }

            if (!workspace.Options.GetOption(RegularExpressionsOptions.ColorizeRegexPatterns, semanticModel.Language))
            {
                return;
            }

            // Do some quick syntactic checks before doing any complex work.
            if (RegexPatternDetector.IsDefinitelyNotPattern(token, _info.SyntaxFacts))
            {
                return;
            }

            var detector = RegexPatternDetector.TryGetOrCreate(semanticModel, _info);
            var tree     = detector?.TryParseRegexPattern(token, cancellationToken);

            if (tree == null)
            {
                return;
            }

            var visitor = _visitorPool.Allocate();

            try
            {
                visitor.Result = result;
                AddClassifications(tree.Root, visitor, result);
            }
            finally
            {
                visitor.Result = null;
                _visitorPool.Free(visitor);
            }
        }