001package gudusoft.gsqlparser.common.structured; 002 003import java.util.Objects; 004 005public final class StructuredPathSegment { 006 007 private final StructuredPathSegmentKind kind; 008 private final String name; 009 010 private StructuredPathSegment(StructuredPathSegmentKind kind, String name) { 011 this.kind = kind; 012 this.name = name; 013 } 014 015 public static StructuredPathSegment arrayElement() { 016 return new StructuredPathSegment(StructuredPathSegmentKind.ARRAY_ELEMENT, null); 017 } 018 019 public static StructuredPathSegment field(String name) { 020 if (name == null || name.isEmpty()) { 021 throw new IllegalArgumentException("field name must be non-empty"); 022 } 023 return new StructuredPathSegment(StructuredPathSegmentKind.FIELD, name); 024 } 025 026 public static StructuredPathSegment mapKey() { 027 return new StructuredPathSegment(StructuredPathSegmentKind.MAP_KEY, null); 028 } 029 030 public static StructuredPathSegment mapValue() { 031 return new StructuredPathSegment(StructuredPathSegmentKind.MAP_VALUE, null); 032 } 033 034 /** A subscript whose container (array or map) is not known yet; see {@link StructuredPathSegmentKind#SUBSCRIPT}. */ 035 public static StructuredPathSegment subscript() { 036 return new StructuredPathSegment(StructuredPathSegmentKind.SUBSCRIPT, null); 037 } 038 039 /** The wildcard of {@code customer.*}: every field of the path before it. */ 040 public static StructuredPathSegment star() { 041 return new StructuredPathSegment(StructuredPathSegmentKind.STAR, null); 042 } 043 044 public StructuredPathSegmentKind getKind() { 045 return kind; 046 } 047 048 public String getName() { 049 return name; 050 } 051 052 public String toDisplayString() { 053 switch (kind) { 054 case ARRAY_ELEMENT: return "[*]"; 055 case FIELD: return "." + name; 056 case MAP_KEY: return "[key]"; 057 // a map value displays as an element, as every map read of the tree has: m['k'] reads m[*] 058 case MAP_VALUE: return "[*]"; 059 case SUBSCRIPT: return "[*]"; 060 case STAR: return ".*"; 061 default: throw new IllegalStateException("unknown kind " + kind); 062 } 063 } 064 065 @Override 066 public boolean equals(Object o) { 067 if (this == o) return true; 068 if (!(o instanceof StructuredPathSegment)) return false; 069 StructuredPathSegment other = (StructuredPathSegment) o; 070 return kind == other.kind && Objects.equals(name, other.name); 071 } 072 073 @Override 074 public int hashCode() { 075 return Objects.hash(kind, name); 076 } 077 078 @Override 079 public String toString() { 080 return toDisplayString(); 081 } 082}