antlr/antlr4 · warning · UnsupportedOperationException

This method is not implemented for readonly sets.

Error message

This method is not implemented for readonly sets.

What it means

ATNConfigSet.contains(Object) delegates to configLookup, but setReadonly(true) sets configLookup to null because cached DFA sets no longer support mutation or lookup. Membership queries on such readonly sets are therefore unsupported.

Source

Thrown at runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java:278

		}

		return configs.hashCode();
	}

	@Override
	public int size() {
		return configs.size();
	}

	@Override
	public boolean isEmpty() {
		return configs.isEmpty();
	}

	@Override
	public boolean contains(Object o) {
		if (configLookup == null) {
			throw new UnsupportedOperationException("This method is not implemented for readonly sets.");
		}

		return configLookup.contains(o);
	}

	public boolean containsFast(ATNConfig obj) {
		if (configLookup == null) {
			throw new UnsupportedOperationException("This method is not implemented for readonly sets.");
		}

		return configLookup.containsFast(obj);
	}

	@Override
	public Iterator<ATNConfig> iterator() {
		return configs.iterator();
	}

View on GitHub (pinned to 7d5770395b)

Solutions

  1. For readonly sets, iterate configs and compare state.stateNumber, alt, and semanticContext as the internal comparator does.
  2. Check !configs.isReadonly() before calling contains.
  3. Copy into a new ATNConfigSet if lookup semantics are required.
  4. Avoid generic Set operations that are unsupported for cached DFA configurations.

Example fix

// before
boolean found = dfaState.configs.contains(config); // readonly

// after
boolean found = containsConfigKey(dfaState.configs, config);

static boolean containsConfigKey(ATNConfigSet set, ATNConfig c) {
    for (ATNConfig x : set.getElements()) {
        if (x.state.stateNumber == c.state.stateNumber
                && x.alt == c.alt
                && x.semanticContext.equals(c.semanticContext)) {
            return true;
        }
    }
    return false;
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean canUseContains(ATNConfigSet configs) {
    return !configs.isReadonly();
}

Try / catch

try {
    return configs.contains(config);
} catch (UnsupportedOperationException e) {
    // readonly lookup cache is gone; iterate configs instead
}

Prevention

When it happens

Trigger: Calling contains on DFAState.configs or any ATNConfigSet after setReadonly(true); passing readonly sets to generic Set algorithms that call contains.

Common situations: Debug/analysis tools inspecting DFA states and custom set utilities that treat ATNConfigSet as a general java.util.Set.

Related errors


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