antlr/antlr4 · error · NotSupportedException

interval ${interval} outside buffer: ${bufferStartIndex}..${

Error message

interval ${interval} outside buffer: ${bufferStartIndex}..${bufferStartIndex+n-1}

What it means

Even a structurally valid interval must lie entirely inside UnbufferedCharStream's current rolling buffer. If its start precedes the buffer or its stop lies beyond buffered/filled data, GetText cannot reconstruct that text and throws NotSupportedException. This is the fundamental random-access limitation of an unbuffered stream.

Source

Thrown at runtime/CSharp/src/UnbufferedCharStream.cs:442

        }

        public virtual string GetText(Interval interval)
        {
            if (interval.a < 0 || interval.b < interval.a - 1)
            {
                throw new ArgumentException("invalid interval");
            }
            int bufferStartIndex = BufferStartIndex;
            if (n > 0 && data[n - 1] == IntStreamConstants.EOF)
            {
                if (interval.a + interval.Length > bufferStartIndex + n)
                {
                    throw new ArgumentException("the interval extends past the end of the stream");
                }
            }
            if (interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n)
            {
                throw new NotSupportedException("interval " + interval + " outside buffer: " + bufferStartIndex + ".." + (bufferStartIndex + n - 1));
            }
            // convert from absolute to local index
            int i = interval.a - bufferStartIndex;
            // build a UTF-16 string from the Unicode code points in data
            var sb = new StringBuilder(interval.Length);
            for (int offset = 0; offset < interval.Length; offset++) {
                sb.Append(Char.ConvertFromUtf32(data[i + offset]));
            }
            return sb.ToString();
        }

        protected internal int BufferStartIndex
        {
            get
            {
                return currentCharIndex - p;
            }
        }

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Extract text while the interval is still buffered, before consuming beyond it.
  2. Hold a Mark() across any interval that will be needed later.
  3. Use AntlrInputStream or BufferedTokenStream when arbitrary delayed text extraction is required.

Example fix

// before
var chars = new UnbufferedCharStream(reader);
// ... consume far past interval ...
string text = chars.GetText(interval);

// after
var chars = new AntlrInputStream(reader); // preserves all characters
string text = chars.GetText(interval);
Defensive patterns

Strategy: type-guard

Validate before calling

if (stream is UnbufferedCharStream) {
    // extract text now or hold a Mark(); otherwise use AntlrInputStream
}

Type guard

static bool SupportsArbitraryGetText(ICharStream stream) => stream is not UnbufferedCharStream;

Try / catch

try { text = chars.GetText(interval); }
catch (NotSupportedException ex) when (ex.Message.StartsWith("interval ") && ex.Message.Contains("outside buffer")) { /* switch to buffered input */ }

Prevention

When it happens

Trigger: Calling GetText for characters already consumed and discarded; requesting text far ahead before synchronization; extracting source text from old tokens late during a streaming parse.

Common situations: Walking a parse tree and calling GetText() after the parser has advanced; token rewriters or diagnostics that reference old intervals; migration from BufferedTokenStream/AntlrInputStream to unbuffered streaming without redesign.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/83084dbf56cdabc7. Report an issue: GitHub.