{"record":{"id":"245e4bf6aacbbac8","repo":"antlr/antlr4","slug":"this-method-is-not-implemented-for-readonly-sets","errorCode":null,"errorMessage":"This method is not implemented for readonly sets.","messagePattern":"This method is not implemented for readonly sets\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java","lineNumber":278,"sourceCode":"\t\t}\n\n\t\treturn configs.hashCode();\n\t}\n\n\t@Override\n\tpublic int size() {\n\t\treturn configs.size();\n\t}\n\n\t@Override\n\tpublic boolean isEmpty() {\n\t\treturn configs.isEmpty();\n\t}\n\n\t@Override\n\tpublic boolean contains(Object o) {\n\t\tif (configLookup == null) {\n\t\t\tthrow new UnsupportedOperationException(\"This method is not implemented for readonly sets.\");\n\t\t}\n\n\t\treturn configLookup.contains(o);\n\t}\n\n\tpublic boolean containsFast(ATNConfig obj) {\n\t\tif (configLookup == null) {\n\t\t\tthrow new UnsupportedOperationException(\"This method is not implemented for readonly sets.\");\n\t\t}\n\n\t\treturn configLookup.containsFast(obj);\n\t}\n\n\t@Override\n\tpublic Iterator<ATNConfig> iterator() {\n\t\treturn configs.iterator();\n\t}\n","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfigSet.java#L260-L296","documentation":"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.","triggerScenarios":"Calling contains on DFAState.configs or any ATNConfigSet after setReadonly(true); passing readonly sets to generic Set algorithms that call contains.","commonSituations":"Debug/analysis tools inspecting DFA states and custom set utilities that treat ATNConfigSet as a general java.util.Set.","solutions":["For readonly sets, iterate configs and compare state.stateNumber, alt, and semanticContext as the internal comparator does.","Check !configs.isReadonly() before calling contains.","Copy into a new ATNConfigSet if lookup semantics are required.","Avoid generic Set operations that are unsupported for cached DFA configurations."],"exampleFix":"// before\nboolean found = dfaState.configs.contains(config); // readonly\n\n// after\nboolean found = containsConfigKey(dfaState.configs, config);\n\nstatic boolean containsConfigKey(ATNConfigSet set, ATNConfig c) {\n    for (ATNConfig x : set.getElements()) {\n        if (x.state.stateNumber == c.state.stateNumber\n                && x.alt == c.alt\n                && x.semanticContext.equals(c.semanticContext)) {\n            return true;\n        }\n    }\n    return false;\n}","handlingStrategy":"validation","validationCode":"static boolean canUseContains(ATNConfigSet configs) {\n    return !configs.isReadonly();\n}","typeGuard":null,"tryCatchPattern":"try {\n    return configs.contains(config);\n} catch (UnsupportedOperationException e) {\n    // readonly lookup cache is gone; iterate configs instead\n}","preventionTips":["Check isReadonly() before Set.contains().","Use an explicit comparator-style loop on readonly sets.","Do not pass cached DFA config sets to generic Set algorithms."],"tags":["antlr","java","atn","atn-config-set","readonly","contains"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}