001package gudusoft.gsqlparser.ir.semantic; 002 003import java.util.Objects; 004 005/** 006 * Exact vendor error enrichment for a GSP {@link Diagnostic}. 007 * 008 * <p>This metadata is explanatory only: consumers must continue to branch on 009 * {@link DiagnosticCode}. A vendor error may be attached only when the 010 * diagnostic factory has exact evidence that the vendor's documented cause 011 * matches the source construct. 012 * 013 * <p><b>API status:</b> read-only consumption of analyzer-produced vendor 014 * enrichment is part of Join Analysis Consumption Profile v1. Constructors 015 * are producer-oriented and are outside that profile. 016 */ 017public final class VendorError { 018 019 private final String vendor; 020 private final String code; 021 private final String title; 022 private final String helpUri; 023 private final String matchedProfile; 024 025 public VendorError(String vendor, String code, String title, 026 String helpUri, String matchedProfile) { 027 this.vendor = requireNonEmpty(vendor, "vendor"); 028 this.code = requireNonEmpty(code, "code"); 029 this.title = requireNonEmpty(title, "title"); 030 this.helpUri = requireNonEmpty(helpUri, "helpUri"); 031 this.matchedProfile = matchedProfile == null 032 ? null : requireNonEmpty(matchedProfile, "matchedProfile"); 033 } 034 035 public String getVendor() { 036 return vendor; 037 } 038 039 public String getCode() { 040 return code; 041 } 042 043 public String getTitle() { 044 return title; 045 } 046 047 public String getHelpUri() { 048 return helpUri; 049 } 050 051 /** @return matched dialect profile, or {@code null} when not profile-specific. */ 052 public String getMatchedProfile() { 053 return matchedProfile; 054 } 055 056 private static String requireNonEmpty(String value, String name) { 057 Objects.requireNonNull(value, name); 058 if (value.trim().isEmpty()) { 059 throw new IllegalArgumentException(name + " must not be empty"); 060 } 061 return value; 062 } 063 064 @Override 065 public boolean equals(Object o) { 066 if (this == o) return true; 067 if (!(o instanceof VendorError)) return false; 068 VendorError that = (VendorError) o; 069 return vendor.equals(that.vendor) 070 && code.equals(that.code) 071 && title.equals(that.title) 072 && helpUri.equals(that.helpUri) 073 && Objects.equals(matchedProfile, that.matchedProfile); 074 } 075 076 @Override 077 public int hashCode() { 078 return Objects.hash(vendor, code, title, helpUri, matchedProfile); 079 } 080 081 @Override 082 public String toString() { 083 return code + " (" + vendor + "): " + title; 084 } 085}