001package gudusoft.gsqlparser.lineage.v2.shape; 002 003/** 004 * The base of every mirror of the shape layer (plan {@code docs/designs/data-lineage/09-sqllr-v2-runtime-driven- 005 * coverage-plan-zh.md}, slice 1b): an immutable value copy of one live object the SQL-LR producer reads (a parse tree 006 * node, a token, a runtime model object, a resolver result, a catalog object, a recorder record), taken when the 007 * analysis froze. A mirror keeps the simple name and the getters of its live class, so producer code reads a mirror 008 * as it read the live object, and holds no live object: references to other mirrors are handles into its 009 * {@link Shape}. 010 * 011 * <p>Mirrors are compared by identity, as the live objects were: one mirror per live object.</p> 012 * 013 * <p>Internal API of the SQL-LR producer.</p> 014 * 015 * @since 4.2.17 016 */ 017public abstract class ShapeObject { 018 019 final Shape shape; 020 final int handle; 021 022 protected ShapeObject(Shape shape, int handle) { 023 this.shape = shape; 024 this.handle = handle; 025 } 026 027 /** The handle of the mirror in its shape. */ 028 public final int shapeHandle() { 029 return handle; 030 } 031 032 /** The shape the mirror belongs to. */ 033 public final Shape shape() { 034 return shape; 035 } 036 037 /** The simple name of the live object's class (a mirror stands for its nearest mirrored class). */ 038 public final String liveSimpleName() { 039 return shape.liveSimpleName(handle); 040 } 041 042 /** The name of the live object's class. */ 043 public final String liveClassName() { 044 return shape.liveClassName(handle); 045 } 046 047 /** 048 * A mirror has text only where the live object's rendering was taken (names, literals, type names, leaf 049 * expressions; their mirrors override this): any other {@code toString()}, including an implicit one in a string 050 * concatenation, would print the mirror instead of what the live object printed, so it fails. 051 */ 052 @Override 053 public String toString() { 054 throw new IllegalStateException("SQL-LR shape: " + liveClassName() + " #" + handle + " has no rendering"); 055 } 056 057 /** Resolves a slot: a value, a handle to another mirror, a list of handles, or a getter that threw. */ 058 protected final <T> T slot(Object slot) { 059 return shape.resolve(slot); 060 } 061}