package net.minecraft.command.descriptors; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections4.trie.PatriciaTrie; import net.minecraft.command.IPermission; import net.minecraft.command.SyntaxErrorException; import net.minecraft.command.arg.ArgWrapper; import net.minecraft.command.arg.CompoundArg; import net.minecraft.command.arg.Processable; import net.minecraft.command.arg.TypedWrapper; import net.minecraft.command.completion.ITabCompletion; import net.minecraft.command.completion.TCDSet; import net.minecraft.command.completion.TabCompletion; import net.minecraft.command.completion.TabCompletionData; import net.minecraft.command.descriptors.SelectorDescriptorDefault.DefaultParserData; import net.minecraft.command.parser.CompletionParser.CompletionData; import net.minecraft.command.parser.Parser; import net.minecraft.command.type.IDataType; import net.minecraft.command.type.management.TypeID; public abstract class SelectorDescriptorDefault extends SelectorDescriptor<DefaultParserData> { public static class DefaultParserData extends SParserData { public final List<Processable> toProcess = new ArrayList<>(); public final PatriciaTrie<TypedWrapper<?>> namedParams = new PatriciaTrie<>(); public final List<TypedWrapper<?>> unnamedParams = new ArrayList<>(); public DefaultParserData(final Parser parser) { super(parser); } @Override public ArgWrapper<?> finalize(final ArgWrapper<?> selector) { return CompoundArg.create(this.toProcess, selector); } @Override public boolean requiresKey() { return !this.namedParams.isEmpty(); } } private final List<IDataType<?>> unnamedTypes; private final Map<String, IDataType<?>> namedTypes; private final List<String> keyMapping; private final Set<ITabCompletion> keyCompletions; public SelectorDescriptorDefault(final List<IDataType<?>> unnamedTypes, final Map<String, IDataType<?>> namedTypes, final List<String> keyMapping, final Set<TypeID<?>> resultTypes, final IPermission permission) { super(resultTypes, permission); this.unnamedTypes = unnamedTypes; this.namedTypes = namedTypes; this.keyMapping = keyMapping; this.keyCompletions = new HashSet<>(namedTypes.size()); for (final String key : namedTypes.keySet()) { final String s = key + "="; this.keyCompletions.add(new TabCompletion(s, s, key)); } } @Override public void complete(final TCDSet tcDataSet, final Parser parser, final int startIndex, final CompletionData cData, final DefaultParserData data) { final Set<String> keySet = new HashSet<>(this.keyMapping.size() - data.unnamedParams.size() + data.namedParams.size()); for (int i = 0; i < data.unnamedParams.size(); ++i) if (this.keyMapping.get(i) != null) keySet.add(this.keyMapping.get(i)); keySet.addAll(data.namedParams.keySet()); for (final ITabCompletion tc : this.keyCompletions) if (!keySet.contains(tc.name.toLowerCase())) TabCompletionData.addToSet(tcDataSet, startIndex, cData, tc); } @Override public void parse(final Parser parser, final String key, final DefaultParserData data) throws SyntaxErrorException { final IDataType<?> valueType = this.namedTypes.get(key); if (valueType == null) throw parser.SEE("Unknown parameter key '" + key + "' encountered "); data.namedParams.put(key, valueType.parse(parser).addToProcess(data.toProcess)); } @Override public void parse(final Parser parser, final DefaultParserData data) throws SyntaxErrorException { if (this.unnamedTypes.size() <= data.unnamedParams.size()) throw parser.SEE("Too many unnamed parameters encountered while parsing selector (", ")"); final IDataType<?> valueType = this.unnamedTypes.get(data.unnamedParams.size()); final ArgWrapper<?> value = valueType.parse(parser); data.unnamedParams.add(value.addToProcess(data.toProcess)); } @Override public DefaultParserData newParserData(final Parser parser) { return new DefaultParserData(parser); } }