package net.minecraft.util.parsing.packrat.commands; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.util.parsing.packrat.Atom; import net.minecraft.util.parsing.packrat.Dictionary; import net.minecraft.util.parsing.packrat.ErrorCollector; import net.minecraft.util.parsing.packrat.ErrorEntry; import net.minecraft.util.parsing.packrat.ParseState; public record Grammar(Dictionary rules, Atom top) { public Optional parse(ParseState parseState) { return parseState.parseTopRule(this.top); } public T parseForCommands(StringReader reader) throws CommandSyntaxException { ErrorCollector.LongestOnly longestOnly = new ErrorCollector.LongestOnly<>(); StringReaderParserState stringReaderParserState = new StringReaderParserState(this.rules(), longestOnly, reader); Optional optional = this.parse(stringReaderParserState); if (optional.isPresent()) { return (T)optional.get(); } else { List list = longestOnly.entries().stream().mapMulti((errorEntry, consumer) -> { if (errorEntry.reason() instanceof Exception exceptionx) { consumer.accept(exceptionx); } }).toList(); for (Exception exception : list) { if (exception instanceof CommandSyntaxException commandSyntaxException) { throw commandSyntaxException; } } if (list.size() == 1 && list.get(0) instanceof RuntimeException runtimeException) { throw runtimeException; } else { throw new IllegalStateException("Failed to parse: " + (String)longestOnly.entries().stream().map(ErrorEntry::toString).collect(Collectors.joining(", "))); } } } public CompletableFuture parseForSuggestions(SuggestionsBuilder builder) { StringReader stringReader = new StringReader(builder.getInput()); stringReader.setCursor(builder.getStart()); ErrorCollector.LongestOnly longestOnly = new ErrorCollector.LongestOnly<>(); StringReaderParserState stringReaderParserState = new StringReaderParserState(this.rules(), longestOnly, stringReader); this.parse(stringReaderParserState); List> list = longestOnly.entries(); if (list.isEmpty()) { return builder.buildFuture(); } else { SuggestionsBuilder suggestionsBuilder = builder.createOffset(longestOnly.cursor()); for (ErrorEntry errorEntry : list) { if (errorEntry.suggestions() instanceof ResourceSuggestion resourceSuggestion) { SharedSuggestionProvider.suggestResource(resourceSuggestion.possibleResources(), suggestionsBuilder); } else { SharedSuggestionProvider.suggest(errorEntry.suggestions().possibleValues(stringReaderParserState), suggestionsBuilder); } } return suggestionsBuilder.buildFuture(); } } }