package net.minecraft.util.parsing.packrat; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; import javax.annotation.Nullable; public class Dictionary { private final Map, Dictionary.Entry> terms = new IdentityHashMap<>(); public NamedRule put(Atom p_333993_, Rule p_397298_) { Dictionary.Entry entry = (Dictionary.Entry)this.terms.computeIfAbsent(p_333993_, Dictionary.Entry::new); if (entry.value != null) { throw new IllegalArgumentException("Trying to override rule: " + p_333993_); } else { entry.value = p_397298_; return entry; } } public NamedRule putComplex(Atom p_393852_, Term p_391921_, Rule.RuleAction p_393539_) { return this.put(p_393852_, Rule.fromTerm(p_391921_, p_393539_)); } public NamedRule put(Atom p_329080_, Term p_392956_, Rule.SimpleRuleAction p_396305_) { return this.put(p_329080_, Rule.fromTerm(p_392956_, p_396305_)); } public void checkAllBound() { List> list = this.terms.entrySet().stream().filter(p_396134_ -> p_396134_.getValue() == null).map(Map.Entry::getKey).toList(); if (!list.isEmpty()) { throw new IllegalStateException("Unbound names: " + list); } } public NamedRule getOrThrow(Atom p_397598_) { return (NamedRule)Objects.requireNonNull(this.terms.get(p_397598_), () -> "No rule called " + p_397598_); } public NamedRule forward(Atom p_392500_) { return this.getOrCreateEntry(p_392500_); } private Dictionary.Entry getOrCreateEntry(Atom p_395883_) { return (Dictionary.Entry)this.terms.computeIfAbsent(p_395883_, Dictionary.Entry::new); } public Term named(Atom p_392444_) { return new Dictionary.Reference<>(this.getOrCreateEntry(p_392444_), p_392444_); } public Term namedWithAlias(Atom p_396057_, Atom p_391365_) { return new Dictionary.Reference<>(this.getOrCreateEntry(p_396057_), p_391365_); } static class Entry implements NamedRule, Supplier { private final Atom name; @Nullable Rule value; private Entry(Atom p_396611_) { this.name = p_396611_; } @Override public Atom name() { return this.name; } @Override public Rule value() { return Objects.requireNonNull(this.value, this); } public String get() { return "Unbound rule " + this.name; } } record Reference(Dictionary.Entry ruleToParse, Atom nameToStore) implements Term { @Override public boolean parse(ParseState p_397182_, Scope p_391380_, Control p_391695_) { T t = p_397182_.parse(this.ruleToParse); if (t == null) { return false; } else { p_391380_.put(this.nameToStore, t); return true; } } } }