private void ParseBuffer(ITextSnapshot textSnapshot)
        {
            var tokenBuilder     = new TokenBuilder(_buffer);
            var statementBuilder = new StatementBuilder(textSnapshot);

            foreach (var tokenSpan in tokenBuilder.GetTokenSpans(0, textSnapshot.Length))
            {
                ProcessTokenSpan(tokenSpan, tokenBuilder, statementBuilder);
            }

            _tagSpans.Update(textSnapshot, _statements.TagSpans);
        }
        private void ParseBufferChanges(INormalizedTextChangeCollection textChanges, ITextSnapshot textSnapshot)
        {
            // We must feed the GLSLTagSpanCollection ALL tagSpans, old and new, and it will determine what the appropriate differences are
            var tokenBuilder     = new TokenBuilder(_buffer);
            var statementBuilder = new StatementBuilder(textSnapshot);

            // Returns any tagspans from our original set (before the text changed) that intersects in any way with our text changes
            _statements.Translate(textSnapshot);
            _commentTagger.Translate(textSnapshot);
            //_bracketTagger.Translate(textSnapshot);
            _variableTagger.Translate(textSnapshot);
            _functionTagger.Translate(textSnapshot);

            foreach (var textChange in textChanges)
            {
                // "Reprocess" statement here instead, so we can track which statements and spans we are removing
                var preprocessorSpan = _statements.ReprocessPreprocessors(textChange.NewPosition, textChange.NewEnd);
                _commentTagger.Remove(preprocessorSpan);

                // Need to translate and remove redundant spans from VariableTagger, FunctionTagger
                var statementSpan = _statements.ReprocessStatements(textChange.NewPosition, textChange.NewEnd);
                _variableTagger.Remove(statementSpan);
                _functionTagger.Remove(statementSpan);

                var span = Span.FromBounds(Math.Min(preprocessorSpan.Start, statementSpan.Start), Math.Max(preprocessorSpan.End, statementSpan.End));

                // For now, we can just determine to RE-PARSE the entirety of the current statement that we are in
                // This is easy enough, but we ALSO need to remove any tag spans that relate to this statement, since we don't want to end up re-adding those tag spans
                if (tokenBuilder.Position <= span.Start)
                {
                    // Now we generate token spans until
                    //  1) we have parsed at least the full textChange.NewLength amount, and
                    //  2) we finish whatever statement we are currently on
                    foreach (var tokenSpan in tokenBuilder.GetTokenSpans(span.Start, Math.Max(textChange.NewLength + span.Start, span.End)))
                    {
                        ProcessTokenSpan(tokenSpan, tokenBuilder, statementBuilder);
                    }
                }
            }

            _tagSpans.Update(textSnapshot, _statements.TagSpans);
        }