All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mojang.brigadier.context.CommandContextBuilder Maven / Gradle / Ivy

The newest version!
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

package com.mojang.brigadier.context;

import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.RedirectModifier;
import com.mojang.brigadier.tree.CommandNode;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class CommandContextBuilder {
    private final Map> arguments = new LinkedHashMap<>();
    private final CommandNode rootNode;
    private final List> nodes = new ArrayList<>();
    private final CommandDispatcher dispatcher;
    private S source;
    private Command command;
    private CommandContextBuilder child;
    private StringRange range;
    private RedirectModifier modifier = null;
    private boolean forks;

    public CommandContextBuilder(final CommandDispatcher dispatcher, final S source, final CommandNode rootNode, final int start) {
        this.rootNode = rootNode;
        this.dispatcher = dispatcher;
        this.source = source;
        this.range = StringRange.at(start);
    }

    public CommandContextBuilder withSource(final S source) {
        this.source = source;
        return this;
    }

    public S getSource() {
        return source;
    }

    public CommandNode getRootNode() {
        return rootNode;
    }

    public CommandContextBuilder withArgument(final String name, final ParsedArgument argument) {
        this.arguments.put(name, argument);
        return this;
    }

    public Map> getArguments() {
        return arguments;
    }

    public CommandContextBuilder withCommand(final Command command) {
        this.command = command;
        return this;
    }

    public CommandContextBuilder withNode(final CommandNode node, final StringRange range) {
        nodes.add(new ParsedCommandNode<>(node, range));
        this.range = StringRange.encompassing(this.range, range);
        this.modifier = node.getRedirectModifier();
        this.forks = node.isFork();
        return this;
    }

    public CommandContextBuilder copy() {
        final CommandContextBuilder copy = new CommandContextBuilder<>(dispatcher, source, rootNode, range.getStart());
        copy.command = command;
        copy.arguments.putAll(arguments);
        copy.nodes.addAll(nodes);
        copy.child = child;
        copy.range = range;
        copy.forks = forks;
        return copy;
    }

    public CommandContextBuilder withChild(final CommandContextBuilder child) {
        this.child = child;
        return this;
    }

    public CommandContextBuilder getChild() {
        return child;
    }

    public CommandContextBuilder getLastChild() {
        CommandContextBuilder result = this;
        while (result.getChild() != null) {
            result = result.getChild();
        }
        return result;
    }

    public Command getCommand() {
        return command;
    }

    public List> getNodes() {
        return nodes;
    }

    public CommandContext build(final String input) {
        return new CommandContext<>(source, input, arguments, command, rootNode, nodes, range, child == null ? null : child.build(input), modifier, forks);
    }

    public CommandDispatcher getDispatcher() {
        return dispatcher;
    }

    public StringRange getRange() {
        return range;
    }

    public SuggestionContext findSuggestionContext(final int cursor) {
        if (range.getStart() <= cursor) {
            if (range.getEnd() < cursor) {
                if (child != null) {
                    return child.findSuggestionContext(cursor);
                } else if (!nodes.isEmpty()) {
                    final ParsedCommandNode last = nodes.get(nodes.size() - 1);
                    return new SuggestionContext<>(last.getNode(), last.getRange().getEnd() + 1);
                } else {
                    return new SuggestionContext<>(rootNode, range.getStart());
                }
            } else {
                CommandNode prev = rootNode;
                for (final ParsedCommandNode node : nodes) {
                    final StringRange nodeRange = node.getRange();
                    if (nodeRange.getStart() <= cursor && cursor <= nodeRange.getEnd()) {
                        return new SuggestionContext<>(prev, nodeRange.getStart());
                    }
                    prev = node.getNode();
                }
                if (prev == null) {
                    throw new IllegalStateException("Can't find node before cursor");
                }
                return new SuggestionContext<>(prev, range.getStart());
            }
        }
        throw new IllegalStateException("Can't find node before cursor");
    }
}