package net.minecraft.command.descriptors; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; 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.CommandArg; import net.minecraft.command.arg.PermissionWrapper; import net.minecraft.command.completion.ITabCompletion; import net.minecraft.command.completion.TabCompletion.Escaped; import net.minecraft.command.completion.TabCompletion.SingleChar; import net.minecraft.command.parser.Context; import net.minecraft.command.parser.Parser; import net.minecraft.command.type.IDataType; import net.minecraft.command.type.management.TypeID; public abstract class OperatorDescriptor { private static final PatriciaTrie<OperatorDescriptor> operators = new PatriciaTrie<>(); public static final Map<ITabCompletion, IPermission> operatorCompletions = new HashMap<>(); private final Set<TypeID<?>> resultTypes; private final IPermission permission; private final List<IDataType<?>> operands; public static final OperatorDescriptor getDescriptor(final String name) { return operators.get(name.toLowerCase()); } public static final void clear() { operators.clear(); operatorCompletions.clear(); } public static final void register(final String name, final ITabCompletion completion, final OperatorDescriptor descriptor) { if (operators.put(name.toLowerCase(), descriptor) != null) throw new IllegalArgumentException("Operator already registerd: " + name); operatorCompletions.put(completion, descriptor.permission); for (final TypeID<?> resultType : descriptor.resultTypes) resultType.addOperator(completion, descriptor.permission); } public static final void register(final String name, final OperatorDescriptor descriptor) { register(name, name.length() == 1 ? new SingleChar(name.charAt(0)) : new Escaped(name), descriptor); } public OperatorDescriptor(final Set<TypeID<?>> resultTypes, final IPermission permission, final List<IDataType<?>> operands) { this.resultTypes = resultTypes; this.operands = operands; this.permission = permission; } public OperatorDescriptor(final Set<TypeID<?>> resultTypes, final IPermission permission, final IDataType<?>... operands) { this.resultTypes = resultTypes; this.permission = permission; this.operands = Arrays.asList(operands); } public abstract ArgWrapper<?> construct(ListOperands operands) throws SyntaxErrorException; public final ArgWrapper<?> parse(final Parser parser, final Context context) throws SyntaxErrorException { final ListOperands operands = this.operands.isEmpty() ? null : new ListOperands(this.operands.size()); for (final IDataType<?> operand : this.operands) operands.add(operand.parse(parser, context)); return PermissionWrapper.wrap(this.construct(operands), this.permission); } public static class Primitive extends OperatorDescriptor { public Primitive(final Set<TypeID<?>> resultTypes, final IPermission permission, final IDataType<?> operand) { super(resultTypes, permission, operand); } @Override public ArgWrapper<?> construct(final ListOperands operands) { return operands.get(); } } public static class ListOperands { private final List<ArgWrapper<?>> operands; public ListOperands() { this.operands = new ArrayList<>(); } public ListOperands(final int initialSize) { this.operands = new ArrayList<>(initialSize); } public ArgWrapper<?> get() { return this.operands.get(this.index++); } public void add(final ArgWrapper<?> operand) { this.operands.add(operand); } private int index = 0; public <T> CommandArg<T> get(final TypeID<T> type) { return this.operands.get(this.index++).get(type); } } }