001package gudusoft.gsqlparser.lineage2.contract; 002 003/** 004 * Contract {@code Transformation} (lineage2-contract.md §4.2, D-08): 005 * original expression text, normalized form (FINGERPRINT-V1 normalization 006 * family), SHA-256 of the normalized form, and the location of the 007 * <em>original</em> expression in the unit (the normalized form is a 008 * canonical rewrite and intentionally has no coordinates). 009 * 010 * <p>Unlike {@link Endpoint}, the JSON form always carries both the 011 * {@code sourceLocation} and {@code locationNullReason} keys (one of the 012 * two is null) — the gold-fixture-pinned shape. 013 * 014 * <p>Internal API: not part of the public gsqlparser surface. 015 */ 016public final class Transformation { 017 018 private final String originalExpression; 019 private final String normalizedExpression; 020 private final String expressionHash; 021 private final SourceLocation sourceLocation; 022 private final LocationNullReason locationNullReason; 023 024 public Transformation(String originalExpression, String normalizedExpression, 025 String expressionHash, SourceLocation sourceLocation, 026 LocationNullReason locationNullReason) { 027 if (originalExpression == null || normalizedExpression == null 028 || expressionHash == null) { 029 throw new IllegalArgumentException("originalExpression, " 030 + "normalizedExpression, and expressionHash must not be null"); 031 } 032 this.originalExpression = originalExpression; 033 this.normalizedExpression = normalizedExpression; 034 this.expressionHash = expressionHash; 035 this.sourceLocation = sourceLocation; 036 this.locationNullReason = locationNullReason; 037 } 038 039 /** 040 * Convenience factory: normalizes {@code originalExpression} with the 041 * FINGERPRINT-V1 normalization family and hashes the normalized form. 042 */ 043 public static Transformation of(String originalExpression, 044 SourceLocation sourceLocation, 045 LocationNullReason locationNullReason) { 046 String normalized = FingerprintV1.normalize(originalExpression); 047 return new Transformation(originalExpression, normalized, 048 GuidEncoder.sha256Hex(normalized), sourceLocation, 049 locationNullReason); 050 } 051 052 public String getOriginalExpression() { 053 return originalExpression; 054 } 055 056 public String getNormalizedExpression() { 057 return normalizedExpression; 058 } 059 060 public String getExpressionHash() { 061 return expressionHash; 062 } 063 064 /** Nullable. */ 065 public SourceLocation getSourceLocation() { 066 return sourceLocation; 067 } 068 069 /** Nullable — set only when {@code sourceLocation} is null. */ 070 public LocationNullReason getLocationNullReason() { 071 return locationNullReason; 072 } 073}