summaryrefslogtreecommitdiff
path: root/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java
blob: e1a62fa712a95bc9f19be0faacb1f061c171fb7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package io.dico.dicore.command.parameter.type;

import io.dico.dicore.Reflection;
import io.dico.dicore.command.CommandException;
import io.dico.dicore.command.ExecutionContext;
import io.dico.dicore.command.annotation.Range;
import io.dico.dicore.command.parameter.ArgumentBuffer;
import io.dico.dicore.command.parameter.Parameter;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * A parameter type.
 * Takes care of parsing, default values as well as completions.
 *
 * @param <TReturn>    type of the parameter
 * @param <TParamInfo> the info object type for the parameter (Example: {@link Range.Memory}
 */
public abstract class ParameterType<TReturn, TParamInfo> {
    private final Class<TReturn> returnType;
    private final ParameterConfig<?, TParamInfo> parameterConfig;
    protected final ParameterType<TReturn, TParamInfo> otherType; // flag or non-flag, depending on current

    public ParameterType(Class<TReturn> returnType) {
        this(returnType, null);
    }

    public ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> paramConfig) {
        this.returnType = Objects.requireNonNull(returnType);
        this.parameterConfig = paramConfig;

        ParameterType<TReturn, TParamInfo> otherType = flagTypeParameter();
        this.otherType = otherType == null ? this : otherType;
    }

    protected ParameterType(Class<TReturn> returnType, ParameterConfig<?, TParamInfo> parameterConfig, ParameterType<TReturn, TParamInfo> otherType) {
        this.returnType = returnType;
        this.parameterConfig = parameterConfig;
        this.otherType = otherType;
    }

    public int getExpectedAmountOfConsumedArguments() {
        return 1;
    }

    public boolean canBeFlag() {
        return this == otherType;
    }

    public boolean isFlagExplicitly() {
        return this instanceof FlagParameterType;
    }

    /**
     * @return The return type
     */
    public final Class<TReturn> getReturnType() {
        return returnType;
    }

    public final Class<?> getAnnotationClass() {
        return parameterConfig == null ? null : parameterConfig.getAnnotationClass();
    }

    public final ParameterConfig<?, TParamInfo> getParameterConfig() {
        return parameterConfig;
    }

    public ParameterKey getTypeKey() {
        return new ParameterKey(returnType, parameterConfig != null ? parameterConfig.getAnnotationClass() : null);
    }

    public ParameterKey getInfolessTypeKey() {
        return new ParameterKey(returnType, null);
    }

    protected FlagParameterType<TReturn, TParamInfo> flagTypeParameter() {
        return null;
    }

    public ParameterType<TReturn, TParamInfo> asFlagParameter() {
        return canBeFlag() ? this : otherType;
    }

    public ParameterType<TReturn, TParamInfo> asNormalParameter() {
        return isFlagExplicitly() ? otherType : this;
    }

    public abstract TReturn parse(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException;

    public TReturn parseForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException {
        return parse(parameter, context.getSender(), buffer);
    }

    public TReturn getDefaultValue(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
        return null;
    }

    public TReturn getDefaultValueForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, ArgumentBuffer buffer) throws CommandException {
        return getDefaultValue(parameter, context.getSender(), buffer);
    }

    public List<String> complete(Parameter<TReturn, TParamInfo> parameter, CommandSender sender, Location location, ArgumentBuffer buffer) {
        return Collections.emptyList();
    }

    public List<String> completeForContext(Parameter<TReturn, TParamInfo> parameter, ExecutionContext context, Location location, ArgumentBuffer buffer) {
        return complete(parameter, context.getSender(), location, buffer);
    }

    protected static abstract class FlagParameterType<TResult, TParamInfo> extends ParameterType<TResult, TParamInfo> {

        protected FlagParameterType(ParameterType<TResult, TParamInfo> otherType) {
            super(otherType.returnType, otherType.parameterConfig, otherType);
        }

        @Override
        public int getExpectedAmountOfConsumedArguments() {
            return otherType.getExpectedAmountOfConsumedArguments();
        }

        @Override
        public boolean canBeFlag() {
            return true;
        }

        @Override
        protected final FlagParameterType<TResult, TParamInfo> flagTypeParameter() {
            return this;
        }

        @Override
        public ParameterType<TResult, TParamInfo> asFlagParameter() {
            return this;
        }

        @Override
        public ParameterType<TResult, TParamInfo> asNormalParameter() {
            return otherType;
        }

    }

}