001package gudusoft.gsqlparser.resolver2.model;
002
003import gudusoft.gsqlparser.resolver2.ResolutionStatus;
004
005/**
006 * The complete result of resolving a column reference.
007 * Contains status, source(s), and optional error information.
008 *
009 * This is the primary data structure stored in TObjectName.resolution
010 */
011public class ResolutionResult {
012    private final ResolutionStatus status;
013    private final ColumnSource columnSource;
014    private final AmbiguousColumnSource ambiguousSource;
015    private final String errorMessage;
016
017    /**
018     * Private constructor - use factory methods instead
019     */
020    private ResolutionResult(ResolutionStatus status,
021                            ColumnSource columnSource,
022                            AmbiguousColumnSource ambiguousSource,
023                            String errorMessage) {
024        this.status = status;
025        this.columnSource = columnSource;
026        this.ambiguousSource = ambiguousSource;
027        this.errorMessage = errorMessage;
028    }
029
030    /**
031     * Creates a successful exact match result
032     */
033    public static ResolutionResult exactMatch(ColumnSource source) {
034        if (source == null) {
035            throw new IllegalArgumentException("Column source cannot be null for exact match");
036        }
037        return new ResolutionResult(ResolutionStatus.EXACT_MATCH, source, null, null);
038    }
039
040    /**
041     * Creates an ambiguous result with multiple candidates
042     */
043    public static ResolutionResult ambiguous(AmbiguousColumnSource ambiguousSource) {
044        if (ambiguousSource == null || ambiguousSource.getCandidateCount() == 0) {
045            throw new IllegalArgumentException("Ambiguous source must have at least one candidate");
046        }
047        return new ResolutionResult(ResolutionStatus.AMBIGUOUS, null, ambiguousSource, null);
048    }
049
050    /**
051     * Creates a not found result
052     */
053    public static ResolutionResult notFound(String columnName) {
054        String message = "Column '" + columnName + "' not found in any visible table";
055        return new ResolutionResult(ResolutionStatus.NOT_FOUND, null, null, message);
056    }
057
058    /**
059     * Creates a not found result with custom error message
060     */
061    public static ResolutionResult notFound(String columnName, String errorMessage) {
062        return new ResolutionResult(ResolutionStatus.NOT_FOUND, null, null, errorMessage);
063    }
064
065    public ResolutionStatus getStatus() {
066        return status;
067    }
068
069    public ColumnSource getColumnSource() {
070        return columnSource;
071    }
072
073    public AmbiguousColumnSource getAmbiguousSource() {
074        return ambiguousSource;
075    }
076
077    public String getErrorMessage() {
078        return errorMessage;
079    }
080
081    public boolean isExactMatch() {
082        return status == ResolutionStatus.EXACT_MATCH;
083    }
084
085    public boolean isAmbiguous() {
086        return status == ResolutionStatus.AMBIGUOUS;
087    }
088
089    public boolean isNotFound() {
090        return status == ResolutionStatus.NOT_FOUND;
091    }
092
093    public boolean isResolved() {
094        return status != ResolutionStatus.NOT_FOUND;
095    }
096
097    @Override
098    public String toString() {
099        switch (status) {
100            case EXACT_MATCH:
101                return "Exact match: " + columnSource;
102            case AMBIGUOUS:
103                return ambiguousSource.toString();
104            case NOT_FOUND:
105                return errorMessage;
106            default:
107                return "Unknown status";
108        }
109    }
110}