-
-
Notifications
You must be signed in to change notification settings - Fork 102
/
MiniMessage.java
296 lines (273 loc) · 11.2 KB
/
MiniMessage.java
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2022 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text.minimessage;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tree.Node;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import net.kyori.adventure.util.Buildable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* MiniMessage is a textual representation of components.
*
* <p>This class allows you to serialize and deserialize them, strip
* or escape them.</p>
*
* @since 4.10.0
*/
public interface MiniMessage extends ComponentSerializer<Component, Component, String>, Buildable<MiniMessage, MiniMessage.Builder> {
/**
* Gets a simple instance without markdown support.
*
* @return a simple instance
* @since 4.10.0
*/
static @NotNull MiniMessage miniMessage() {
return MiniMessageImpl.INSTANCE;
}
/**
* Escapes all known tags in the input message, so that they are ignored in deserialization.
*
* <p>Useful for untrusted input.</p>
*
* <p>Only globally known tags will be escaped. Use the overload that takes a {@link TagResolver} if any custom tags should be handled.</p>
*
* @param input the input message, with potential tags
* @return the output, with escaped tags
* @since 4.10.0
*/
@NotNull String escapeTags(final @NotNull String input);
/**
* Escapes all known tags in the input message, so that they are ignored in deserialization.
*
* <p>Useful for untrusted input.</p>
*
* @param input the input message, with potential tags
* @param tagResolver the tag resolver for any additional tags to handle
* @return the output, with escaped tags
* @since 4.10.0
*/
@NotNull String escapeTags(final @NotNull String input, final @NotNull TagResolver tagResolver);
/**
* Escapes all known tags in the input message, so that they are ignored in deserialization.
*
* <p>Useful for untrusted input.</p>
*
* @param input the input message, with potential tags
* @param tagResolvers a series of tag resolvers to apply extra tags from, last specified taking priority
* @return the output, with escaped tags
* @since 4.10.0
*/
default @NotNull String escapeTags(final @NotNull String input, final @NotNull TagResolver... tagResolvers) {
return this.escapeTags(input, TagResolver.resolver(tagResolvers));
}
/**
* Removes all supported tags in the input message.
*
* <p>Useful for untrusted input.</p>
*
* <p>Only globally known tags will be stripped. Use the overload that takes a {@link TagResolver} if any custom tags should be handled.</p>
*
* @param input the input message, with potential tags
* @return the output, without tags
* @since 4.10.0
*/
@NotNull String stripTags(final @NotNull String input);
/**
* Removes all known tags in the input message, so that they are ignored in deserialization.
*
* <p>Useful for untrusted input.</p>
*
* @param input the input message, with tags
* @param tagResolver the tag resolver for any additional tags to handle
* @return the output, without tags
* @since 4.10.0
*/
@NotNull String stripTags(final @NotNull String input, final @NotNull TagResolver tagResolver);
/**
* Removes all known tags in the input message, so that they are ignored in deserialization.
*
* <p>Useful for untrusted input.</p>
*
* @param input the input message, with tags
* @param tagResolvers a series of tag resolvers to apply extra tags from, last specified taking priority
* @return the output, without tags
* @since 4.10.0
*/
default @NotNull String stripTags(final @NotNull String input, final @NotNull TagResolver... tagResolvers) {
return this.stripTags(input, TagResolver.resolver(tagResolvers));
}
/**
* Deserializes a string into a component, with a tag resolver to parse tags of the form {@code <key>}.
*
* <p>Tags will be resolved from the resolver parameter before the resolver provided in the builder is used.</p>
*
* @param input the input string
* @param tagResolver the tag resolver for any additional tags to handle
* @return the output component
* @since 4.10.0
*/
@NotNull Component deserialize(final @NotNull String input, final @NotNull TagResolver tagResolver);
/**
* Deserializes a string into a component, with a tag resolver to parse tags of the form {@code <key>}.
*
* <p>Tags will be resolved from the resolver parameters before the resolver provided in the builder is used.</p>
*
* @param input the input string
* @param tagResolvers a series of tag resolvers to apply extra tags from, last specified taking priority
* @return the output component
* @since 4.10.0
*/
default @NotNull Component deserialize(final @NotNull String input, final @NotNull TagResolver... tagResolvers) {
return this.deserialize(input, TagResolver.resolver(tagResolvers));
}
/**
* Deserializes a string into a tree of parsed elements,
* This is intended for inspecting the output of the parser for debugging purposes.
*
* @param input the input string
* @return the root of the resulting tree
* @since 4.10.0
*/
@NotNull Node deserializeToTree(@NotNull String input);
/**
* Deserializes a string into a tree of parsed elements, with a tag resolver to parse tags of the form {@code <key>}.
* This is intended for inspecting the output of the parser for debugging purposes.
*
* <p>Tags will be resolved from the resolver parameter before the resolver provided in the builder is used.</p>
*
* @param input the input string
* @param tagResolver the tag resolver for any additional tags to handle
* @return the root of the resulting tree
* @since 4.10.0
*/
@NotNull Node deserializeToTree(final @NotNull String input, final @NotNull TagResolver tagResolver);
/**
* Deserializes a string into a tree of parsed elements, with a tag resolver to parse tags of the form {@code <key>}.
* This is intended for inspecting the output of the parser for debugging purposes.
*
* <p>Tags will be resolved from the resolver parameter before the resolver provided in the builder is used.</p>
*
* @param input the input string
* @param tagResolvers a series of tag resolvers to apply extra tags from, last specified taking priority
* @return the root of the resulting tree
* @since 4.10.0
*/
default @NotNull Node deserializeToTree(final @NotNull String input, final @NotNull TagResolver... tagResolvers) {
return this.deserializeToTree(input, TagResolver.resolver(tagResolvers));
}
/**
* Creates a new {@link MiniMessage.Builder}.
*
* @return a builder
* @since 4.10.0
*/
static Builder builder() {
return new MiniMessageImpl.BuilderImpl();
}
/**
* A builder for {@link MiniMessage}.
*
* @since 4.10.0
*/
interface Builder extends Buildable.Builder<MiniMessage> {
/**
* Set the known tags to the provided tag resolver.
*
* <p>This resolver determines the base set of tags known to this {@link MiniMessage} instance.
* Any resolvers passed to the {@link MiniMessage#deserialize(String, TagResolver)} method will override this resolver.</p>
*
* @param tags the tag resolver to use
* @return this builder
* @since 4.10.0
*/
@NotNull Builder tags(final @NotNull TagResolver tags);
/**
* Add to the set of known tags this MiniMessage instance can use.
*
* @param adder a function operating on a builder containing currently known tags
* @return this builder
* @since 4.10.0
*/
@NotNull Builder editTags(final @NotNull Consumer<TagResolver.Builder> adder);
/**
* Enables strict mode (disabled by default).
*
* <p>By default, MiniMessage will allow {@link net.kyori.adventure.text.minimessage.tag.Inserting#allowsChildren() child-allowing} tags to be implicitly closed. When strict mode
* is enabled, all child-allowing tags which are {@code <opened>} must be explicitly {@code </closed>} as well.</p>
*
* <p>Additionally, the {@link net.kyori.adventure.text.minimessage.tag.ParserDirective#RESET reset tag} is disabled in this mode.
* Any usage of this tag will throw a parser exception if strict mode is enabled.</p>
*
* @param strict if strict mode should be enabled
* @return this builder
* @since 4.10.0
*/
@NotNull Builder strict(final boolean strict);
/**
* Print debug information to the given output (disabled by default).
*
* <p>Debug output includes detailed information about the parsing process to help debug parser behavior.</p>
*
* <p>The consumer will receive line fragments terminated by {@code LF}, not complete lines.
* This avoids string concatenation within debug output generation. If the consumer is {@code null}, no debug information will be generated.</p>
*
* @param debugOutput if debug mode should be enabled
* @return this builder
* @since 4.10.0
*/
@NotNull Builder debug(final @Nullable Consumer<String> debugOutput);
/**
* If in lenient mode, MiniMessage will output helpful messages.
*
* <p>This method allows you to change how they should be printed. By default, they will be printed to standard out.</p>
*
* @param consumer the error message consumer
* @return this builder
* @since 4.10.0
*/
@NotNull Builder parsingErrorMessageConsumer(final @NotNull Consumer<List<String>> consumer);
/**
* Specify a function that takes the component at the end of the parser process.
* <p>By default, this compacts the resulting component with {@link Component#compact()}.</p>
*
* @param postProcessor method run at the end of parsing
* @return this builder
* @since 4.10.0
*/
@NotNull Builder postProcessor(final @NotNull UnaryOperator<Component> postProcessor);
/**
* Builds the serializer.
*
* @return the built serializer
* @since 4.10.0
*/
@Override
@NotNull MiniMessage build();
}
}