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.DelayedException; 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.NamedRule; import net.minecraft.util.parsing.packrat.ParseState; public record Grammar(Dictionary rules, NamedRule top) implements CommandArgumentParser { public Grammar(Dictionary rules, NamedRule top) { rules.checkAllBound(); this.rules = rules; this.top = top; } public Optional parse(ParseState parseState) { return parseState.parseTopRule(this.top); } @Override public T parseForCommands(StringReader reader) throws CommandSyntaxException { ErrorCollector.LongestOnly longestOnly = new ErrorCollector.LongestOnly<>(); StringReaderParserState stringReaderParserState = new StringReaderParserState(longestOnly, reader); Optional optional = this.parse(stringReaderParserState); if (optional.isPresent()) { return (T)optional.get(); } else { List> list = longestOnly.entries(); List list2 = list.stream().mapMulti((errorEntry, consumer) -> { if (errorEntry.reason() instanceof DelayedException delayedException) { consumer.accept(delayedException.create(reader.getString(), errorEntry.cursor())); } else if (errorEntry.reason() instanceof Exception exceptionx) { consumer.accept(exceptionx); } }).toList(); for (Exception exception : list2) { if (exception instanceof CommandSyntaxException commandSyntaxException) { throw commandSyntaxException; } } if (list2.size() == 1 && list2.get(0) instanceof RuntimeException runtimeException) { throw runtimeException; } else { throw new IllegalStateException("Failed to parse: " + (String)list.stream().map(ErrorEntry::toString).collect(Collectors.joining(", "))); } } } @Override 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(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(); } } }