package net.minecraft.core; import com.mojang.datafixers.util.Either; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.Spliterator; import java.util.function.Function; import java.util.stream.Stream; import javax.annotation.Nullable; import net.minecraft.Util; import net.minecraft.tags.TagKey; import net.minecraft.util.RandomSource; import org.jetbrains.annotations.VisibleForTesting; public interface HolderSet extends Iterable> { Stream> stream(); int size(); boolean isBound(); Either, List>> unwrap(); Optional> getRandomElement(RandomSource p_235712_); Holder get(int p_205798_); boolean contains(Holder p_205799_); boolean canSerializeIn(HolderOwner p_255749_); Optional> unwrapKey(); @Deprecated @VisibleForTesting static HolderSet.Named emptyNamed(HolderOwner p_255858_, TagKey p_256459_) { return new HolderSet.Named(p_255858_, p_256459_) { @Override protected List> contents() { throw new UnsupportedOperationException("Tag " + this.key() + " can't be dereferenced during construction"); } }; } static HolderSet empty() { return (HolderSet)HolderSet.Direct.EMPTY; } @SafeVarargs static HolderSet.Direct direct(Holder... p_205810_) { return new HolderSet.Direct<>(List.of(p_205810_)); } static HolderSet.Direct direct(List> p_205801_) { return new HolderSet.Direct<>(List.copyOf(p_205801_)); } @SafeVarargs static HolderSet.Direct direct(Function> p_205807_, E... p_205808_) { return direct(Stream.of(p_205808_).map(p_205807_).toList()); } static HolderSet.Direct direct(Function> p_205804_, Collection p_298882_) { return direct(p_298882_.stream().map(p_205804_).toList()); } public static final class Direct extends HolderSet.ListBacked { static final HolderSet.Direct EMPTY = new HolderSet.Direct(List.of()); private final List> contents; @Nullable private Set> contentsSet; Direct(List> p_205814_) { this.contents = p_205814_; } @Override protected List> contents() { return this.contents; } @Override public boolean isBound() { return true; } @Override public Either, List>> unwrap() { return Either.right(this.contents); } @Override public Optional> unwrapKey() { return Optional.empty(); } @Override public boolean contains(Holder p_205816_) { if (this.contentsSet == null) { this.contentsSet = Set.copyOf(this.contents); } return this.contentsSet.contains(p_205816_); } @Override public String toString() { return "DirectSet[" + this.contents + "]"; } @Override public boolean equals(Object p_335031_) { return this == p_335031_ ? true : p_335031_ instanceof HolderSet.Direct direct && this.contents.equals(direct.contents); } @Override public int hashCode() { return this.contents.hashCode(); } } public abstract static class ListBacked implements HolderSet { protected abstract List> contents(); @Override public int size() { return this.contents().size(); } @Override public Spliterator> spliterator() { return this.contents().spliterator(); } @Override public Iterator> iterator() { return this.contents().iterator(); } @Override public Stream> stream() { return this.contents().stream(); } @Override public Optional> getRandomElement(RandomSource p_235714_) { return Util.getRandomSafe(this.contents(), p_235714_); } @Override public Holder get(int p_205823_) { return this.contents().get(p_205823_); } @Override public boolean canSerializeIn(HolderOwner p_255876_) { return true; } } public static class Named extends HolderSet.ListBacked { private final HolderOwner owner; private final TagKey key; @Nullable private List> contents; Named(HolderOwner p_256118_, TagKey p_256597_) { this.owner = p_256118_; this.key = p_256597_; } void bind(List> p_205836_) { this.contents = List.copyOf(p_205836_); } public TagKey key() { return this.key; } @Override protected List> contents() { if (this.contents == null) { throw new IllegalStateException("Trying to access unbound tag '" + this.key + "' from registry " + this.owner); } else { return this.contents; } } @Override public boolean isBound() { return this.contents != null; } @Override public Either, List>> unwrap() { return Either.left(this.key); } @Override public Optional> unwrapKey() { return Optional.of(this.key); } @Override public boolean contains(Holder p_205834_) { return p_205834_.is(this.key); } @Override public String toString() { return "NamedSet(" + this.key + ")[" + this.contents + "]"; } @Override public boolean canSerializeIn(HolderOwner p_256542_) { return this.owner.canSerializeIn(p_256542_); } } }