TextComponentTagVisitor.java
net.minecraft.nbt.TextComponentTagVisitor
信息
- 全限定名:net.minecraft.nbt.TextComponentTagVisitor
- 类型:public class
- 包:net.minecraft.nbt
- 源码路径:src/main/java/net/minecraft/nbt/TextComponentTagVisitor.java
- 起始行号:L19
- 实现:TagVisitor
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L20 - 说明:
TODO
- 类型:
-
INLINE_LIST_THRESHOLD- 类型:
int - 修饰符:
private static final - 源码定位:
L21 - 说明:
TODO
- 类型:
-
MAX_DEPTH- 类型:
int - 修饰符:
private static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
MAX_LENGTH- 类型:
int - 修饰符:
private static final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
SIMPLE_VALUE- 类型:
Pattern - 修饰符:
private static final - 源码定位:
L24 - 说明:
TODO
- 类型:
-
NEWLINE- 类型:
Component - 修饰符:
private static final - 源码定位:
L25 - 说明:
TODO
- 类型:
-
ELEMENT_SPACING- 类型:
Component - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
indentation- 类型:
String - 修饰符:
private final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
styling- 类型:
TextComponentTagVisitor.Styling - 修饰符:
private final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
sortKeys- 类型:
boolean - 修饰符:
private final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
indentDepth- 类型:
int - 修饰符:
private - 源码定位:
L30 - 说明:
TODO
- 类型:
-
depth- 类型:
int - 修饰符:
private - 源码定位:
L31 - 说明:
TODO
- 类型:
-
result- 类型:
MutableComponent - 修饰符:
private final - 源码定位:
L32 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.nbt.TextComponentTagVisitor.PlainStyling- 类型:
class - 修饰符:
public static - 源码定位:
L309 - 说明:
TODO
- 类型:
-
net.minecraft.nbt.TextComponentTagVisitor.RichStyling- 类型:
class - 修饰符:
public static - 源码定位:
L340 - 说明:
TODO
- 类型:
-
net.minecraft.nbt.TextComponentTagVisitor.Styling- 类型:
interface - 修饰符:
public - 源码定位:
L389 - 说明:
TODO
- 类型:
-
net.minecraft.nbt.TextComponentTagVisitor.Token- 类型:
enum - 修饰符:
public static - 源码定位:
L399 - 说明:
TODO
- 类型:
构造器
public TextComponentTagVisitor(String indentation) @ L34
- 构造器名:TextComponentTagVisitor
- 源码定位:L34
- 修饰符:public
参数:
- indentation: String
说明:
TODO
public TextComponentTagVisitor(String indentation, TextComponentTagVisitor.Styling styling) @ L38
- 构造器名:TextComponentTagVisitor
- 源码定位:L38
- 修饰符:public
参数:
- indentation: String
- styling: TextComponentTagVisitor.Styling
说明:
TODO
public TextComponentTagVisitor(String indentation, TextComponentTagVisitor.Styling styling, boolean sortKeys) @ L42
- 构造器名:TextComponentTagVisitor
- 源码定位:L42
- 修饰符:public
参数:
- indentation: String
- styling: TextComponentTagVisitor.Styling
- sortKeys: boolean
说明:
TODO
方法
下面的方法块按源码顺序生成。
public Component visit(Tag tag) @ L48
- 方法名:visit
- 源码定位:L48
- 返回类型:Component
- 修饰符:public
参数:
- tag: Tag
说明:
TODO
private TextComponentTagVisitor append(String string, Style style) @ L53
- 方法名:append
- 源码定位:L53
- 返回类型:TextComponentTagVisitor
- 修饰符:private
参数:
- string: String
- style: Style
说明:
TODO
private TextComponentTagVisitor append(Component component) @ L58
- 方法名:append
- 源码定位:L58
- 返回类型:TextComponentTagVisitor
- 修饰符:private
参数:
- component: Component
说明:
TODO
private TextComponentTagVisitor append(TextComponentTagVisitor.Token token) @ L63
- 方法名:append
- 源码定位:L63
- 返回类型:TextComponentTagVisitor
- 修饰符:private
参数:
- token: TextComponentTagVisitor.Token
说明:
TODO
public void visitString(StringTag tag) @ L68
- 方法名:visitString
- 源码定位:L68
- 返回类型:void
- 修饰符:public
参数:
- tag: StringTag
说明:
TODO
public void visitByte(ByteTag tag) @ L75
- 方法名:visitByte
- 源码定位:L75
- 返回类型:void
- 修饰符:public
参数:
- tag: ByteTag
说明:
TODO
public void visitShort(ShortTag tag) @ L80
- 方法名:visitShort
- 源码定位:L80
- 返回类型:void
- 修饰符:public
参数:
- tag: ShortTag
说明:
TODO
public void visitInt(IntTag tag) @ L85
- 方法名:visitInt
- 源码定位:L85
- 返回类型:void
- 修饰符:public
参数:
- tag: IntTag
说明:
TODO
public void visitLong(LongTag tag) @ L90
- 方法名:visitLong
- 源码定位:L90
- 返回类型:void
- 修饰符:public
参数:
- tag: LongTag
说明:
TODO
public void visitFloat(FloatTag tag) @ L95
- 方法名:visitFloat
- 源码定位:L95
- 返回类型:void
- 修饰符:public
参数:
- tag: FloatTag
说明:
TODO
public void visitDouble(DoubleTag tag) @ L100
- 方法名:visitDouble
- 源码定位:L100
- 返回类型:void
- 修饰符:public
参数:
- tag: DoubleTag
说明:
TODO
public void visitByteArray(ByteArrayTag tag) @ L105
- 方法名:visitByteArray
- 源码定位:L105
- 返回类型:void
- 修饰符:public
参数:
- tag: ByteArrayTag
说明:
TODO
public void visitIntArray(IntArrayTag tag) @ L126
- 方法名:visitIntArray
- 源码定位:L126
- 返回类型:void
- 修饰符:public
参数:
- tag: IntArrayTag
说明:
TODO
public void visitLongArray(LongArrayTag tag) @ L147
- 方法名:visitLongArray
- 源码定位:L147
- 返回类型:void
- 修饰符:public
参数:
- tag: LongArrayTag
说明:
TODO
private static boolean shouldWrapListElements(ListTag list) @ L168
- 方法名:shouldWrapListElements
- 源码定位:L168
- 返回类型:boolean
- 修饰符:private static
参数:
- list: ListTag
说明:
TODO
public void visitList(ListTag tag) @ L182
- 方法名:visitList
- 源码定位:L182
- 返回类型:void
- 修饰符:public
参数:
- tag: ListTag
说明:
TODO
public void visitCompound(CompoundTag tag) @ L229
- 方法名:visitCompound
- 源码定位:L229
- 返回类型:void
- 修饰符:public
参数:
- tag: CompoundTag
说明:
TODO
private void appendSubTag(Tag tag, boolean indent) @ L276
- 方法名:appendSubTag
- 源码定位:L276
- 返回类型:void
- 修饰符:private
参数:
- tag: Tag
- indent: boolean
说明:
TODO
private Component handleEscapePretty(String input) @ L294
- 方法名:handleEscapePretty
- 源码定位:L294
- 返回类型:Component
- 修饰符:private
参数:
- input: String
说明:
TODO
public void visitEnd(EndTag tag) @ L305
- 方法名:visitEnd
- 源码定位:L305
- 返回类型:void
- 修饰符:public
参数:
- tag: EndTag
说明:
TODO
代码
public class TextComponentTagVisitor implements TagVisitor {
private static final Logger LOGGER = LogUtils.getLogger();
private static final int INLINE_LIST_THRESHOLD = 8;
private static final int MAX_DEPTH = 64;
private static final int MAX_LENGTH = 128;
private static final Pattern SIMPLE_VALUE = Pattern.compile("[A-Za-z0-9._+-]+");
private static final Component NEWLINE = Component.literal("\n");
private static final Component ELEMENT_SPACING = Component.literal(" ");
private final String indentation;
private final TextComponentTagVisitor.Styling styling;
private final boolean sortKeys;
private int indentDepth;
private int depth;
private final MutableComponent result = Component.empty();
public TextComponentTagVisitor(String indentation) {
this(indentation, TextComponentTagVisitor.RichStyling.INSTANCE);
}
public TextComponentTagVisitor(String indentation, TextComponentTagVisitor.Styling styling) {
this(indentation, styling, LOGGER.isDebugEnabled());
}
public TextComponentTagVisitor(String indentation, TextComponentTagVisitor.Styling styling, boolean sortKeys) {
this.indentation = indentation;
this.styling = styling;
this.sortKeys = sortKeys;
}
public Component visit(Tag tag) {
tag.accept(this);
return this.result;
}
private TextComponentTagVisitor append(String string, Style style) {
this.result.append(Component.literal(string).withStyle(style));
return this;
}
private TextComponentTagVisitor append(Component component) {
this.result.append(component);
return this;
}
private TextComponentTagVisitor append(TextComponentTagVisitor.Token token) {
this.result.append(this.styling.token(token));
return this;
}
@Override
public void visitString(StringTag tag) {
String quoted = StringTag.quoteAndEscape(tag.value());
Component quote = Component.literal(quoted.substring(0, 1));
this.append(quote).append(quoted.substring(1, quoted.length() - 1), this.styling.stringStyle()).append(quote);
}
@Override
public void visitByte(ByteTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.BYTE_SUFFIX);
}
@Override
public void visitShort(ShortTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.SHORT_SUFFIX);
}
@Override
public void visitInt(IntTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle());
}
@Override
public void visitLong(LongTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.LONG_SUFFIX);
}
@Override
public void visitFloat(FloatTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.FLOAT_SUFFIX);
}
@Override
public void visitDouble(DoubleTag tag) {
this.append(String.valueOf(tag.value()), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.DOUBLE_SUFFIX);
}
@Override
public void visitByteArray(ByteArrayTag tag) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN)
.append(TextComponentTagVisitor.Token.BYTE_ARRAY_PREFIX)
.append(TextComponentTagVisitor.Token.LIST_TYPE_SEPARATOR);
byte[] data = tag.getAsByteArray();
for (int i = 0; i < data.length && i < 128; i++) {
this.append(ELEMENT_SPACING).append(String.valueOf(data[i]), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.BYTE_SUFFIX);
if (i != data.length - 1) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR);
}
}
if (data.length > 128) {
this.append(TextComponentTagVisitor.Token.FOLDED);
}
this.append(TextComponentTagVisitor.Token.LIST_CLOSE);
}
@Override
public void visitIntArray(IntArrayTag tag) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN)
.append(TextComponentTagVisitor.Token.INT_ARRAY_PREFIX)
.append(TextComponentTagVisitor.Token.LIST_TYPE_SEPARATOR);
int[] data = tag.getAsIntArray();
for (int i = 0; i < data.length && i < 128; i++) {
this.append(ELEMENT_SPACING).append(String.valueOf(data[i]), this.styling.numberStyle());
if (i != data.length - 1) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR);
}
}
if (data.length > 128) {
this.append(TextComponentTagVisitor.Token.FOLDED);
}
this.append(TextComponentTagVisitor.Token.LIST_CLOSE);
}
@Override
public void visitLongArray(LongArrayTag tag) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN)
.append(TextComponentTagVisitor.Token.LONG_ARRAY_PREFIX)
.append(TextComponentTagVisitor.Token.LIST_TYPE_SEPARATOR);
long[] data = tag.getAsLongArray();
for (int i = 0; i < data.length && i < 128; i++) {
this.append(ELEMENT_SPACING).append(String.valueOf(data[i]), this.styling.numberStyle()).append(TextComponentTagVisitor.Token.LONG_SUFFIX);
if (i != data.length - 1) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR);
}
}
if (data.length > 128) {
this.append(TextComponentTagVisitor.Token.FOLDED);
}
this.append(TextComponentTagVisitor.Token.LIST_CLOSE);
}
private static boolean shouldWrapListElements(ListTag list) {
if (list.size() >= 8) {
return false;
} else {
for (Tag element : list) {
if (!(element instanceof NumericTag)) {
return true;
}
}
return false;
}
}
@Override
public void visitList(ListTag tag) {
if (tag.isEmpty()) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN).append(TextComponentTagVisitor.Token.LIST_CLOSE);
} else if (this.depth >= 64) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN).append(TextComponentTagVisitor.Token.FOLDED).append(TextComponentTagVisitor.Token.LIST_CLOSE);
} else if (!shouldWrapListElements(tag)) {
this.append(TextComponentTagVisitor.Token.LIST_OPEN);
for (int i = 0; i < tag.size(); i++) {
if (i != 0) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR).append(ELEMENT_SPACING);
}
this.appendSubTag(tag.get(i), false);
}
this.append(TextComponentTagVisitor.Token.LIST_CLOSE);
} else {
this.append(TextComponentTagVisitor.Token.LIST_OPEN);
if (!this.indentation.isEmpty()) {
this.append(NEWLINE);
}
Component entryIndent = Component.literal(this.indentation.repeat(this.indentDepth + 1));
Component elementSpacing = this.indentation.isEmpty() ? ELEMENT_SPACING : NEWLINE;
for (int i = 0; i < tag.size() && i < 128; i++) {
this.append(entryIndent);
this.appendSubTag(tag.get(i), true);
if (i != tag.size() - 1) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR).append(elementSpacing);
}
}
if (tag.size() > 128) {
this.append(entryIndent).append(TextComponentTagVisitor.Token.FOLDED);
}
if (!this.indentation.isEmpty()) {
this.append(NEWLINE).append(Component.literal(this.indentation.repeat(this.indentDepth)));
}
this.append(TextComponentTagVisitor.Token.LIST_CLOSE);
}
}
@Override
public void visitCompound(CompoundTag tag) {
if (tag.isEmpty()) {
this.append(TextComponentTagVisitor.Token.STRUCT_OPEN).append(TextComponentTagVisitor.Token.STRUCT_CLOSE);
} else if (this.depth >= 64) {
this.append(TextComponentTagVisitor.Token.STRUCT_OPEN)
.append(TextComponentTagVisitor.Token.FOLDED)
.append(TextComponentTagVisitor.Token.STRUCT_CLOSE);
} else {
this.append(TextComponentTagVisitor.Token.STRUCT_OPEN);
Collection<String> keys;
if (this.sortKeys) {
List<String> keyCopy = new ArrayList<>(tag.keySet());
Collections.sort(keyCopy);
keys = keyCopy;
} else {
keys = tag.keySet();
}
if (!this.indentation.isEmpty()) {
this.append(NEWLINE);
}
Component entryIndent = Component.literal(this.indentation.repeat(this.indentDepth + 1));
Component elementSpacing = this.indentation.isEmpty() ? ELEMENT_SPACING : NEWLINE;
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
this.append(entryIndent)
.append(this.handleEscapePretty(key))
.append(TextComponentTagVisitor.Token.NAME_VALUE_SEPARATOR)
.append(ELEMENT_SPACING);
this.appendSubTag(tag.get(key), true);
if (iterator.hasNext()) {
this.append(TextComponentTagVisitor.Token.ELEMENT_SEPARATOR).append(elementSpacing);
}
}
if (!this.indentation.isEmpty()) {
this.append(NEWLINE).append(Component.literal(this.indentation.repeat(this.indentDepth)));
}
this.append(TextComponentTagVisitor.Token.STRUCT_CLOSE);
}
}
private void appendSubTag(Tag tag, boolean indent) {
if (indent) {
this.indentDepth++;
}
this.depth++;
try {
tag.accept(this);
} finally {
if (indent) {
this.indentDepth--;
}
this.depth--;
}
}
private Component handleEscapePretty(String input) {
if (SIMPLE_VALUE.matcher(input).matches()) {
return Component.literal(input).withStyle(this.styling.keyStyle());
} else {
String quoted = StringTag.quoteAndEscape(input);
String quote = quoted.substring(0, 1);
Component inner = Component.literal(quoted.substring(1, quoted.length() - 1)).withStyle(this.styling.keyStyle());
return Component.literal(quote).append(inner).append(quote);
}
}
@Override
public void visitEnd(EndTag tag) {
}
public static class PlainStyling implements TextComponentTagVisitor.Styling {
public static final TextComponentTagVisitor.Styling INSTANCE = new TextComponentTagVisitor.PlainStyling();
private final Map<TextComponentTagVisitor.Token, Component> tokens = new HashMap<>();
private PlainStyling() {
for (TextComponentTagVisitor.Token value : TextComponentTagVisitor.Token.values()) {
this.tokens.put(value, Component.literal(value.text));
}
}
@Override
public Style keyStyle() {
return Style.EMPTY;
}
@Override
public Style stringStyle() {
return Style.EMPTY;
}
@Override
public Style numberStyle() {
return Style.EMPTY;
}
@Override
public Component token(TextComponentTagVisitor.Token token) {
return Objects.requireNonNull(this.tokens.get(token));
}
}
public static class RichStyling implements TextComponentTagVisitor.Styling {
private static final Style SYNTAX_HIGHLIGHTING_NUMBER_TYPE = Style.EMPTY.withColor(ChatFormatting.RED);
public static final TextComponentTagVisitor.Styling INSTANCE = new TextComponentTagVisitor.RichStyling();
private final Map<TextComponentTagVisitor.Token, Component> tokens = new HashMap<>();
private static final Style SYNTAX_HIGHLIGHTING_KEY = Style.EMPTY.withColor(ChatFormatting.AQUA);
private static final Style SYNTAX_HIGHLIGHTING_STRING = Style.EMPTY.withColor(ChatFormatting.GREEN);
private static final Style SYNTAX_HIGHLIGHTING_NUMBER = Style.EMPTY.withColor(ChatFormatting.GOLD);
private RichStyling() {
this.overrideToken(TextComponentTagVisitor.Token.FOLDED, Style.EMPTY.withColor(ChatFormatting.GRAY));
this.overrideToken(TextComponentTagVisitor.Token.BYTE_SUFFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.BYTE_ARRAY_PREFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.SHORT_SUFFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.INT_ARRAY_PREFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.LONG_SUFFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.LONG_ARRAY_PREFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.FLOAT_SUFFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
this.overrideToken(TextComponentTagVisitor.Token.DOUBLE_SUFFIX, SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
for (TextComponentTagVisitor.Token value : TextComponentTagVisitor.Token.values()) {
this.tokens.putIfAbsent(value, Component.literal(value.text));
}
}
private void overrideToken(TextComponentTagVisitor.Token token, Style style) {
this.tokens.put(token, Component.literal(token.text).withStyle(style));
}
@Override
public Style keyStyle() {
return SYNTAX_HIGHLIGHTING_KEY;
}
@Override
public Style stringStyle() {
return SYNTAX_HIGHLIGHTING_STRING;
}
@Override
public Style numberStyle() {
return SYNTAX_HIGHLIGHTING_NUMBER;
}
@Override
public Component token(TextComponentTagVisitor.Token token) {
return Objects.requireNonNull(this.tokens.get(token));
}
}
public interface Styling {
Style keyStyle();
Style stringStyle();
Style numberStyle();
Component token(final TextComponentTagVisitor.Token token);
}
public static enum Token {
FOLDED("<...>"),
ELEMENT_SEPARATOR(","),
LIST_CLOSE("]"),
LIST_OPEN("["),
LIST_TYPE_SEPARATOR(";"),
STRUCT_CLOSE("}"),
STRUCT_OPEN("{"),
NAME_VALUE_SEPARATOR(":"),
BYTE_SUFFIX("b"),
BYTE_ARRAY_PREFIX("B"),
SHORT_SUFFIX("s"),
INT_ARRAY_PREFIX("I"),
LONG_SUFFIX("L"),
LONG_ARRAY_PREFIX("L"),
FLOAT_SUFFIX("f"),
DOUBLE_SUFFIX("d");
public final String text;
private Token(String text) {
this.text = text;
}
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
StringTag.quoteAndEscape()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
Component.empty(), Component.literal()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Pattern.compile()
- 引用位置: