From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Sat, 12 Sep 2020 16:55:21 -0700
Subject: [PATCH] Optimise tab complete

Some of the toLowerCase calls can be expensive.

diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java
index 103576715ef6ae4df4b216ae9ae31b6fb1086bd5..e8fdbe7b8d8192a3247d98534e78ede7a7314a91 100644
--- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java
+++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java
@@ -590,10 +590,11 @@ public class CommandDispatcher<S> {
         final String truncatedInput = fullInput.substring(0, cursor);
         @SuppressWarnings("unchecked") final CompletableFuture<Suggestions>[] futures = new CompletableFuture[parent.getChildren().size()];
         int i = 0;
+        final String remainingLower = truncatedInput.substring(start).toLowerCase(); // Tuinity
         for (final CommandNode<S> node : parent.getChildren()) {
             CompletableFuture<Suggestions> future = Suggestions.empty();
             try {
-                future = node.listSuggestions(context.build(truncatedInput), new SuggestionsBuilder(truncatedInput, start));
+                future = node.listSuggestions(context.build(truncatedInput), new SuggestionsBuilder(truncatedInput, start, remainingLower)); // Tuinity
             } catch (final CommandSyntaxException ignored) {
             }
             futures[i++] = future;
diff --git a/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java b/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java
index cb993ca102402d9c19ea9fa04e5db09c21205896..849686f7b2a8b0044f7cd14c8c2e401e80966462 100644
--- a/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java
+++ b/src/main/java/com/mojang/brigadier/arguments/BoolArgumentType.java
@@ -34,10 +34,10 @@ public class BoolArgumentType implements ArgumentType<Boolean> {
 
     @Override
     public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
-        if ("true".startsWith(builder.getRemaining().toLowerCase())) {
+        if ("true".startsWith(builder.getRemainingLowercase())) { // Tuinity
             builder.suggest("true");
         }
-        if ("false".startsWith(builder.getRemaining().toLowerCase())) {
+        if ("false".startsWith(builder.getRemainingLowercase())) { // Tuinity
             builder.suggest("false");
         }
         return builder.buildFuture();
diff --git a/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java b/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java
index bc0024adb804ac055a4f8afb7f85d00ec13931e9..0343f6663c450c3f0d9c57d817eef9c979055939 100644
--- a/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java
+++ b/src/main/java/com/mojang/brigadier/suggestion/SuggestionsBuilder.java
@@ -14,9 +14,16 @@ public class SuggestionsBuilder {
     private final String input;
     private final int start;
     private final String remaining;
+    private String remainingLowercase; public final String getRemainingLowercase() { return this.remainingLowercase == null ? this.remainingLowercase = this.remaining.toLowerCase() : this.remainingLowercase; } // Tuinity
     private final List<Suggestion> result = new ArrayList<>();
 
     public SuggestionsBuilder(final String input, final int start) {
+        // Tuinity start
+        this(input, start, null);
+    }
+    public SuggestionsBuilder(final String input, final int start, final String remainingLowercase) {
+        this.remainingLowercase = remainingLowercase;
+        // Tuinity end
         this.input = input;
         this.start = start;
         this.remaining = input.substring(start);
diff --git a/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java b/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java
index 7720578796e28d28e8c0c9aa40155cd205c17d54..e5db29d4cadb5702c7d06b0b6e2d05586a652ec8 100644
--- a/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java
+++ b/src/main/java/com/mojang/brigadier/tree/LiteralCommandNode.java
@@ -20,11 +20,11 @@ import java.util.concurrent.CompletableFuture;
 import java.util.function.Predicate;
 
 public class LiteralCommandNode<S> extends CommandNode<S> {
-    private final String literal;
+    private final String literal; private final String literalLower; // Tuinity
 
     public LiteralCommandNode(final String literal, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
         super(command, requirement, redirect, modifier, forks);
-        this.literal = literal;
+        this.literal = literal; this.literalLower = this.literal.toLowerCase(); // Tuinity
     }
 
     public String getLiteral() {
@@ -66,7 +66,7 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
 
     @Override
     public CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
-        if (literal.toLowerCase().startsWith(builder.getRemaining().toLowerCase())) {
+        if (literalLower.startsWith(builder.getRemainingLowercase())) { // Tuinity
             return builder.suggest(literal).buildFuture();
         } else {
             return Suggestions.empty();
