package net.minecraft.commands.arguments.item; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.mojang.brigadier.ImmutableStringReader; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Dynamic; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import net.minecraft.Util; import net.minecraft.nbt.NbtOps; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Unit; import net.minecraft.util.parsing.packrat.Atom; import net.minecraft.util.parsing.packrat.Dictionary; import net.minecraft.util.parsing.packrat.NamedRule; import net.minecraft.util.parsing.packrat.Scope; import net.minecraft.util.parsing.packrat.Term; import net.minecraft.util.parsing.packrat.commands.Grammar; import net.minecraft.util.parsing.packrat.commands.ResourceLocationParseRule; import net.minecraft.util.parsing.packrat.commands.ResourceLookupRule; import net.minecraft.util.parsing.packrat.commands.StringReaderTerms; import net.minecraft.util.parsing.packrat.commands.TagParseRule; public class ComponentPredicateParser { public static Grammar> createGrammar(ComponentPredicateParser.Context context) { Atom> atom = Atom.of("top"); Atom> atom2 = Atom.of("type"); Atom atom3 = Atom.of("any_type"); Atom atom4 = Atom.of("element_type"); Atom atom5 = Atom.of("tag_type"); Atom> atom6 = Atom.of("conditions"); Atom> atom7 = Atom.of("alternatives"); Atom atom8 = Atom.of("term"); Atom atom9 = Atom.of("negation"); Atom atom10 = Atom.of("test"); Atom atom11 = Atom.of("component_type"); Atom

atom12 = Atom.of("predicate_type"); Atom atom13 = Atom.of("id"); Atom> atom14 = Atom.of("tag"); Dictionary dictionary = new Dictionary<>(); NamedRule namedRule = dictionary.put(atom13, ResourceLocationParseRule.INSTANCE); NamedRule> namedRule2 = dictionary.put( atom, Term.alternative( Term.sequence( dictionary.named(atom2), StringReaderTerms.character('['), Term.cut(), Term.optional(dictionary.named(atom6)), StringReaderTerms.character(']') ), dictionary.named(atom2) ), scope -> { Builder builder = ImmutableList.builder(); scope.getOrThrow(atom2).ifPresent(builder::add); List list = scope.get(atom6); if (list != null) { builder.addAll(list); } return builder.build(); } ); dictionary.put( atom2, Term.alternative(dictionary.named(atom4), Term.sequence(StringReaderTerms.character('#'), Term.cut(), dictionary.named(atom5)), dictionary.named(atom3)), scope -> Optional.ofNullable(scope.getAny(atom4, atom5)) ); dictionary.put(atom3, StringReaderTerms.character('*'), scope -> Unit.INSTANCE); dictionary.put(atom4, new ComponentPredicateParser.ElementLookupRule<>(namedRule, context)); dictionary.put(atom5, new ComponentPredicateParser.TagLookupRule<>(namedRule, context)); dictionary.put( atom6, Term.sequence(dictionary.named(atom7), Term.optional(Term.sequence(StringReaderTerms.character(','), dictionary.named(atom6)))), scope -> { T object = context.anyOf(scope.getOrThrow(atom7)); return (List)Optional.ofNullable(scope.get(atom6)).map(list -> Util.copyAndAdd(object, list)).orElse(List.of(object)); } ); dictionary.put( atom7, Term.sequence(dictionary.named(atom8), Term.optional(Term.sequence(StringReaderTerms.character('|'), dictionary.named(atom7)))), scope -> { T object = scope.getOrThrow(atom8); return (List)Optional.ofNullable(scope.get(atom7)).map(list -> Util.copyAndAdd(object, list)).orElse(List.of(object)); } ); dictionary.put( atom8, Term.alternative(dictionary.named(atom10), Term.sequence(StringReaderTerms.character('!'), dictionary.named(atom9))), scope -> scope.getAnyOrThrow(atom10, atom9) ); dictionary.put(atom9, dictionary.named(atom10), scope -> context.negate(scope.getOrThrow(atom10))); dictionary.putComplex( atom10, Term.alternative( Term.sequence(dictionary.named(atom11), StringReaderTerms.character('='), Term.cut(), dictionary.named(atom14)), Term.sequence(dictionary.named(atom12), StringReaderTerms.character('~'), Term.cut(), dictionary.named(atom14)), dictionary.named(atom11) ), parseState -> { Scope scope = parseState.scope(); P object = scope.get(atom12); try { if (object != null) { Dynamic dynamic = scope.getOrThrow(atom14); return context.createPredicateTest(parseState.input(), object, dynamic); } else { C object2 = scope.getOrThrow(atom11); Dynamic dynamic2 = scope.get(atom14); return dynamic2 != null ? context.createComponentTest(parseState.input(), object2, dynamic2) : context.createComponentTest(parseState.input(), object2); } } catch (CommandSyntaxException var9x) { parseState.errorCollector().store(parseState.mark(), var9x); return null; } } ); dictionary.put(atom11, new ComponentPredicateParser.ComponentLookupRule<>(namedRule, context)); dictionary.put(atom12, new ComponentPredicateParser.PredicateLookupRule<>(namedRule, context)); dictionary.put(atom14, new TagParseRule<>(NbtOps.INSTANCE)); return new Grammar<>(dictionary, namedRule2); } static class ComponentLookupRule extends ResourceLookupRule, C> { ComponentLookupRule(NamedRule idParser, ComponentPredicateParser.Context context) { super(idParser, context); } @Override protected C validateElement(ImmutableStringReader reader, ResourceLocation elementType) throws Exception { return this.context.lookupComponentType(reader, elementType); } @Override public Stream possibleResources() { return this.context.listComponentTypes(); } } public interface Context { T forElementType(ImmutableStringReader reader, ResourceLocation elementType) throws CommandSyntaxException; Stream listElementTypes(); T forTagType(ImmutableStringReader reader, ResourceLocation tagType) throws CommandSyntaxException; Stream listTagTypes(); C lookupComponentType(ImmutableStringReader reader, ResourceLocation componentType) throws CommandSyntaxException; Stream listComponentTypes(); T createComponentTest(ImmutableStringReader reader, C context, Dynamic data) throws CommandSyntaxException; T createComponentTest(ImmutableStringReader reader, C context); P lookupPredicateType(ImmutableStringReader reader, ResourceLocation predicateType) throws CommandSyntaxException; Stream listPredicateTypes(); T createPredicateTest(ImmutableStringReader reader, P predicateType, Dynamic data) throws CommandSyntaxException; T negate(T value); T anyOf(List values); } static class ElementLookupRule extends ResourceLookupRule, T> { ElementLookupRule(NamedRule idParser, ComponentPredicateParser.Context context) { super(idParser, context); } @Override protected T validateElement(ImmutableStringReader reader, ResourceLocation elementType) throws Exception { return this.context.forElementType(reader, elementType); } @Override public Stream possibleResources() { return this.context.listElementTypes(); } } static class PredicateLookupRule extends ResourceLookupRule, P> { PredicateLookupRule(NamedRule idParser, ComponentPredicateParser.Context context) { super(idParser, context); } @Override protected P validateElement(ImmutableStringReader reader, ResourceLocation elementType) throws Exception { return this.context.lookupPredicateType(reader, elementType); } @Override public Stream possibleResources() { return this.context.listPredicateTypes(); } } static class TagLookupRule extends ResourceLookupRule, T> { TagLookupRule(NamedRule idParser, ComponentPredicateParser.Context context) { super(idParser, context); } @Override protected T validateElement(ImmutableStringReader reader, ResourceLocation elementType) throws Exception { return this.context.forTagType(reader, elementType); } @Override public Stream possibleResources() { return this.context.listTagTypes(); } } }