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 java.util.List; import java.util.Optional; import java.util.stream.Stream; import net.minecraft.Util; import net.minecraft.nbt.Tag; 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.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<>(); dictionary.put( atom, Term.alternative( Term.sequence(Term.named(atom2), StringReaderTerms.character('['), Term.cut(), Term.optional(Term.named(atom6)), StringReaderTerms.character(']')), Term.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(Term.named(atom4), Term.sequence(StringReaderTerms.character('#'), Term.cut(), Term.named(atom5)), Term.named(atom3)), scope -> Optional.ofNullable(scope.getAny(atom4, atom5)) ); dictionary.put(atom3, StringReaderTerms.character('*'), scope -> Unit.INSTANCE); dictionary.put(atom4, new ComponentPredicateParser.ElementLookupRule<>(atom13, context)); dictionary.put(atom5, new ComponentPredicateParser.TagLookupRule<>(atom13, context)); dictionary.put(atom6, Term.sequence(Term.named(atom7), Term.optional(Term.sequence(StringReaderTerms.character(','), Term.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(Term.named(atom8), Term.optional(Term.sequence(StringReaderTerms.character('|'), Term.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(Term.named(atom10), Term.sequence(StringReaderTerms.character('!'), Term.named(atom9))), scope -> scope.getAnyOrThrow(atom10, atom9) ); dictionary.put(atom9, Term.named(atom10), scope -> context.negate(scope.getOrThrow(atom10))); dictionary.put( atom10, Term.alternative( Term.sequence(Term.named(atom11), StringReaderTerms.character('='), Term.cut(), Term.named(atom14)), Term.sequence(Term.named(atom12), StringReaderTerms.character('~'), Term.cut(), Term.named(atom14)), Term.named(atom11) ), (parseState, scope) -> { P object = scope.get(atom12); try { if (object != null) { Tag tag = scope.getOrThrow(atom14); return Optional.of(context.createPredicateTest(parseState.input(), object, tag)); } else { C object2 = scope.getOrThrow(atom11); Tag tag2 = scope.get(atom14); return Optional.of( tag2 != null ? context.createComponentTest(parseState.input(), object2, tag2) : context.createComponentTest(parseState.input(), object2) ); } } catch (CommandSyntaxException var9x) { parseState.errorCollector().store(parseState.mark(), var9x); return Optional.empty(); } } ); dictionary.put(atom11, new ComponentPredicateParser.ComponentLookupRule<>(atom13, context)); dictionary.put(atom12, new ComponentPredicateParser.PredicateLookupRule<>(atom13, context)); dictionary.put(atom14, TagParseRule.INSTANCE); dictionary.put(atom13, ResourceLocationParseRule.INSTANCE); return new Grammar<>(dictionary, atom); } static class ComponentLookupRule extends ResourceLookupRule, C> { ComponentLookupRule(Atom 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, Tag value) throws CommandSyntaxException; T createComponentTest(ImmutableStringReader reader, C context); P lookupPredicateType(ImmutableStringReader reader, ResourceLocation predicateType) throws CommandSyntaxException; Stream listPredicateTypes(); T createPredicateTest(ImmutableStringReader reader, P predicate, Tag value) throws CommandSyntaxException; T negate(T value); T anyOf(List values); } static class ElementLookupRule extends ResourceLookupRule, T> { ElementLookupRule(Atom 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(Atom 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(Atom 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(); } } }