antlr/antlr4 · error · UnsupportedOperationException

Unbuffered stream cannot know its size

Error message

Unbuffered stream cannot know its size

What it means

UnbufferedCharStream.size() always throws UnsupportedOperationException because the stream deliberately does not retain the whole input, so total length is unknown until everything is read. This is a design property of the unbuffered streams for processing huge inputs in constant memory, not a transient failure.

Source

Thrown at runtime/Java/src/org/antlr/v4/runtime/UnbufferedCharStream.java:310

		}
		else if (i >= n) {
            throw new UnsupportedOperationException("seek to index outside buffer: "+
                    index+" not in "+getBufferStartIndex()+".."+(getBufferStartIndex()+n));
        }

		p = i;
		currentCharIndex = index;
		if (p == 0) {
			lastChar = lastCharBufferStart;
		}
		else {
			lastChar = data[p-1];
		}
    }

    @Override
    public int size() {
        throw new UnsupportedOperationException("Unbuffered stream cannot know its size");
    }

    @Override
    public String getSourceName() {
		if (name == null || name.isEmpty()) {
			return UNKNOWN_SOURCE_NAME;
		}

		return name;
	}

	@Override
	public String getText(Interval interval) {
		if (interval.a < 0 || interval.b < interval.a - 1) {
			throw new IllegalArgumentException("invalid interval");
		}

		int bufferStartIndex = getBufferStartIndex();

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Use ANTLRInputStream / CharStreams.fromPath (buffered) when you need size()
  2. Pre-compute the length yourself (file length, or a counting pass) and pass it alongside the stream
  3. Gate size()-dependent logic on the stream type before calling it

Example fix

// before
long pct = 100L * stream.index() / stream.size(); // throws

// after
long total = file.length(); // known out-of-band for file input
long pct = 100L * stream.index() / total;
// or use a buffered stream when total size is needed:
CharStream cs = CharStreams.fromPath(path); // size() now works
Defensive patterns

Strategy: fallback

Validate before calling

if (stream instanceof UnbufferedCharStream) {
    long total = knownInputLength; // e.g., file.length(), supplied out-of-band
    use(total);
} else {
    use(stream.size()); // buffered streams support size()
}

Type guard

static boolean supportsSize(CharStream s) {
    return !(s instanceof UnbufferedCharStream);
}

Prevention

When it happens

Trigger: Calling size() directly; generic code (progress bars, percent parsers, progress calculations) that calls size() on any IntStream; library utilities that size the input for buffer allocation.

Common situations: Sharing code between ANTLRInputStream (where size() works) and UnbufferedCharStream; estimating parse progress; third-party helpers assuming a complete CharStream.

Related errors


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