001package gudusoft.gsqlparser.catalog.runtime;
002
003import java.util.Collections;
004import java.util.LinkedHashMap;
005import java.util.Map;
006import java.util.Objects;
007
008/**
009 * Factory + immutable record for {@link CatalogBinding}.
010 *
011 * <p>Plan §7.2. Bindings are produced by {@link CatalogResolver} after a successful lookup
012 * — they pair the input {@link CatalogQualifiedName} with the canonical resolved name and
013 * stable {@link CatalogObjectId} (which usually carries through to bridge mapping).</p>
014 */
015public final class CatalogBindings {
016
017    private CatalogBindings() {
018        // Static factory.
019    }
020
021    public static CatalogBinding of(CatalogEntry entry) {
022        if (entry == null) {
023            throw new IllegalArgumentException("CatalogBindings.of: entry is required");
024        }
025        return new ImmutableCatalogBinding(entry.name(), entry.id(), entry.kind(), entry.properties());
026    }
027
028    public static CatalogBinding of(CatalogQualifiedName resolvedName,
029                                    CatalogObjectId id,
030                                    CatalogObjectKind kind) {
031        return new ImmutableCatalogBinding(resolvedName, id, kind, null);
032    }
033
034    public static CatalogBinding of(CatalogQualifiedName resolvedName,
035                                    CatalogObjectId id,
036                                    CatalogObjectKind kind,
037                                    Map<String, Object> properties) {
038        return new ImmutableCatalogBinding(resolvedName, id, kind, properties);
039    }
040
041    static final class ImmutableCatalogBinding implements CatalogBinding {
042
043        private final CatalogQualifiedName resolvedName;
044        private final CatalogObjectId objectId;
045        private final CatalogObjectKind kind;
046        private final Map<String, Object> properties;
047
048        ImmutableCatalogBinding(CatalogQualifiedName resolvedName,
049                                CatalogObjectId objectId,
050                                CatalogObjectKind kind,
051                                Map<String, Object> properties) {
052            if (resolvedName == null) {
053                throw new IllegalArgumentException("CatalogBinding.resolvedName is required");
054            }
055            if (objectId == null) {
056                throw new IllegalArgumentException("CatalogBinding.objectId is required");
057            }
058            if (kind == null) {
059                throw new IllegalArgumentException("CatalogBinding.kind is required");
060            }
061            this.resolvedName = resolvedName;
062            this.objectId = objectId;
063            this.kind = kind;
064            this.properties = properties == null
065                ? Collections.<String, Object>emptyMap()
066                : Collections.unmodifiableMap(new LinkedHashMap<String, Object>(properties));
067        }
068
069        @Override
070        public CatalogQualifiedName resolvedName() {
071            return resolvedName;
072        }
073
074        @Override
075        public CatalogObjectId objectId() {
076            return objectId;
077        }
078
079        @Override
080        public CatalogObjectKind kind() {
081            return kind;
082        }
083
084        @Override
085        public Map<String, Object> properties() {
086            return properties;
087        }
088
089        @Override
090        public boolean equals(Object o) {
091            if (this == o) return true;
092            if (!(o instanceof ImmutableCatalogBinding)) return false;
093            ImmutableCatalogBinding that = (ImmutableCatalogBinding) o;
094            return resolvedName.equals(that.resolvedName)
095                && objectId.equals(that.objectId)
096                && kind == that.kind
097                && properties.equals(that.properties);
098        }
099
100        @Override
101        public int hashCode() {
102            return Objects.hash(resolvedName, objectId, kind, properties);
103        }
104
105        @Override
106        public String toString() {
107            return "CatalogBinding{name=" + resolvedName + ", id=" + objectId + ", kind=" + kind + '}';
108        }
109    }
110}