package net.minecraft.command.construction; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import net.minecraft.command.IPermission; import net.minecraft.command.construction.CommandDescriptorDefault.CParserData; import net.minecraft.command.descriptors.CommandDescriptor; import net.minecraft.command.descriptors.ICommandDescriptor.UsageProvider; import net.minecraft.command.type.IExParse; public abstract class CommandProtoDescriptor { public final Set<String> names; private final UsageProvider usage; public final IPermission permission; public boolean useEmptyConstructable = false; public final List<IExParse<Void, ? super CParserData>> args = new ArrayList<>(); public final List<CommandProtoDescriptor> subCommands = new ArrayList<>(); public CommandProtoDescriptor(final String name, final List<String> aliases, final IPermission permission, final UsageProvider usage) { this.usage = usage; this.permission = permission; this.names = new HashSet<>(1 + aliases.size()); this.names.add(name); this.names.addAll(aliases); } public Pair<Set<String>, CommandDescriptor<CParserData>> construct(final CommandConstructable constructable) { final Map<String, CommandDescriptor<? super CParserData>> subCommands = new HashMap<>(this.subCommands.size()); for (final CommandProtoDescriptor subCommand : this.subCommands) { final Pair<Set<String>, CommandDescriptor<CParserData>> data = subCommand.construct(constructable); for (final String name : data.getLeft()) subCommands.put(name, data.getRight()); } return new ImmutablePair<Set<String>, CommandDescriptor<CParserData>>( this.names, new CommandDescriptorConstructable( this.useEmptyConstructable ? CommandConstructable.emptyConstructable : constructable, this.permission, this.usage, this.args, subCommands)); } public static class Constructable extends CommandProtoDescriptor { public final CommandConstructable constructable; private Pair<Set<String>, CommandDescriptor<CParserData>> ret = null; public Constructable(final String name, final List<String> aliases, final CommandConstructable constructable, final IPermission permission, final UsageProvider usage) { super(name, aliases, permission, usage); this.constructable = constructable; } public Constructable(final String name, final List<String> aliases, final CommandConstructable constructable, final UsageProvider usage) { this(name, aliases, constructable, null, usage); } @Override public Pair<Set<String>, CommandDescriptor<CParserData>> construct(final CommandConstructable constructable) { if (this.ret == null) this.ret = super.construct(this.constructable); return this.ret; } } public static class NoConstructable extends CommandProtoDescriptor { private final Map<CommandConstructable, Pair<Set<String>, CommandDescriptor<CParserData>>> cachedRet = new HashMap<>(); public NoConstructable(final String name, final List<String> aliases, final IPermission permission, final UsageProvider usage) { super(name, aliases, permission, usage); } public NoConstructable(final String name, final List<String> aliases, final UsageProvider usage) { this(name, aliases, null, usage); } @Override public Pair<Set<String>, CommandDescriptor<CParserData>> construct(final CommandConstructable constructable) { Pair<Set<String>, CommandDescriptor<CParserData>> ret = this.cachedRet.get(constructable); if (ret == null) { ret = super.construct(constructable); this.cachedRet.put(constructable, ret); } return ret; } } }