001package gudusoft.gsqlparser.lineage.v2.fold; 002 003/** 004 * The label of a fold walk ({@code algorithms/fold-v1.md}, Section 5.1): {@code VALUE}, or {@code ROW} with a 005 * role. Labels compose with {@link #compose}; {@code VALUE} is the identity. 006 * 007 * @since 4.2.17 008 */ 009public final class FoldLabel { 010 011 /** The label of a walk of {@code VALUE} micro-edges only. */ 012 public static final FoldLabel VALUE = new FoldLabel("VALUE", null); 013 014 private static final String PROPAGATION = "ROW_PROPAGATION"; 015 016 private final String kind; 017 private final String role; 018 019 private FoldLabel(String kind, String role) { 020 this.kind = kind; 021 this.role = role; 022 } 023 024 /** The label of one micro-edge or Fact: {@code VALUE} for kind {@code VALUE}, otherwise {@code ROW(role)}. */ 025 public static FoldLabel of(Object kind, Object role) { 026 return "VALUE".equals(kind) ? VALUE : row(role instanceof String ? (String) role : null); 027 } 028 029 /** {@code ROW(role)}; a null role stands for a role that is absent. */ 030 public static FoldLabel row(String role) { 031 return new FoldLabel("ROW", role); 032 } 033 034 /** {@code VALUE} or {@code ROW}. */ 035 public String getKind() { 036 return kind; 037 } 038 039 /** The role of a {@code ROW} label; null for {@code VALUE}. */ 040 public String getRole() { 041 return role; 042 } 043 044 public boolean isValue() { 045 return this == VALUE; 046 } 047 048 /** {@code this ยท next}: Section 5.1 of fold-v1. */ 049 public FoldLabel compose(FoldLabel next) { 050 if (isValue()) { 051 return next; 052 } 053 if (!PROPAGATION.equals(role)) { 054 return this; 055 } 056 return next.isValue() ? this : next; 057 } 058 059 /** 060 * The text the reference runner sorts labels by (Python {@code repr} of its label tuple): {@code ('ROW', 061 * 'FILTER')}, {@code ('ROW', None)}, {@code ('VALUE',)}. 062 */ 063 String sortText() { 064 if (isValue()) { 065 return "('VALUE',)"; 066 } 067 return role == null ? "('ROW', None)" : "('ROW', '" + role + "')"; 068 } 069 070 @Override 071 public boolean equals(Object other) { 072 if (!(other instanceof FoldLabel)) { 073 return false; 074 } 075 FoldLabel label = (FoldLabel) other; 076 return kind.equals(label.kind) && (role == null ? label.role == null : role.equals(label.role)); 077 } 078 079 @Override 080 public int hashCode() { 081 return kind.hashCode() * 31 + (role == null ? 0 : role.hashCode()); 082 } 083 084 @Override 085 public String toString() { 086 return isValue() ? "VALUE" : "ROW " + role; 087 } 088}