public final class CanonicalJson extends Object
canonical-json-v1 of SQL-LR (lineage-spec/algorithms/canonical-json-v1.md): the strict
reader of Section 3, the RFC 8785 writer restricted to integers of Section 4, and the array ordering of
the DOCUMENT mode (Sections 5 and 6).
A JSON value is one of these Java objects: Map<String, Object> (members in input order),
List<Object>, String, Long, Boolean, or null for JSON null. The
reader returns exactly these types; the writer also accepts Integer, Short, Byte
and BigInteger within the integer range.
The reference implementation is lineage-spec/algorithms/reference/sqllr_ids.py
(parse_json_strict, jcs_bytes, canonicalize_document). Where the two can report
different codes for one input, this class reports the code the reference reports: the parse runs left to
right, a duplicate member name is detected when its object closes, and an unpaired surrogate is reported
only after the whole text parsed.
Every traversal uses an explicit stack, so nesting is limited by MAX_DEPTH alone, not by the
thread's stack size. A value nested deeper is SCHEMA_INVALID_JSON for the reader, the writer and
the canonicalizer alike, so the writer never produces bytes the reader rejects. (The reference raises an
uncaught RecursionError from about 500 levels on; no fixture comes near either limit.)
| Modifier and Type | Class and Description |
|---|---|
static class |
CanonicalJson.Mode
The two modes of Section 2, and the
DOCUMENT mode that rejects unregistered arrays. |
| Modifier and Type | Field and Description |
|---|---|
static int |
MAX_DEPTH
The most objects and arrays that may enclose one another; the outermost container is level 1.
|
static long |
MAX_SAFE_INTEGER
2^53 - 1: the largest integer the format admits (Section 3, rule 7).
|
static String |
SCHEMA_DUPLICATE_KEY |
static String |
SCHEMA_INVALID_JSON |
static String |
SCHEMA_NON_INTEGER_NUMBER |
static String |
SCHEMA_VIOLATION |
static String |
SEMANTIC_ARRAY_KIND_VIOLATION |
| Modifier and Type | Method and Description |
|---|---|
static byte[] |
canonicalBytes(byte[] data,
CanonicalJson.Mode mode)
The canonical bytes of JSON input bytes in the given mode.
|
static Object |
canonicalizeDocument(Object value,
boolean strict)
canonicalizeDocument(value, strict, ArrayRegistry.standard(), null). |
static Object |
canonicalizeDocument(Object value,
boolean strict,
ArrayRegistry registry,
List<String> notes)
A copy of a lineage document with every
SET array sorted by its registered key; every
SEQUENCE and DISPLAY_ORDER array, and every array in open content, keeps its order. |
static int |
compareTyped(Object a,
Object b)
The total order of Section 6.2 over JSON values: absent or
null < false <
true < integers (numerically) < strings (unsigned UTF-8 bytes) < arrays and objects
(their canonical bytes, unsigned). |
static int |
compareUnsigned(byte[] a,
byte[] b)
Unsigned lexicographic order of byte arrays.
|
static byte[] |
documentBytes(Object value)
jcsBytes(canonicalizeDocument(value, true)): the canonical wire form of a lineage document. |
static Object |
immutableCopy(Object value)
A deep copy of a JSON value in which every object and array is unmodifiable.
|
static boolean |
isInteger(Object value)
True for a JSON integer (not a boolean).
|
static byte[] |
jcsBytes(Object value)
The RFC 8785 bytes of a value, every array in its current order (
JCS mode). |
static String |
jcsText(Object value)
The RFC 8785 text of a value, every array in its current order.
|
static Object |
parse(byte[] data)
Parses JSON bytes under the eight input rules of Section 3.
|
public static final long MAX_SAFE_INTEGER
public static final int MAX_DEPTH
SCHEMA_INVALID_JSON.public static final String SCHEMA_INVALID_JSON
public static final String SCHEMA_DUPLICATE_KEY
public static final String SCHEMA_NON_INTEGER_NUMBER
public static final String SCHEMA_VIOLATION
public static final String SEMANTIC_ARRAY_KIND_VIOLATION
public static Object parse(byte[] data)
SqllrException - SCHEMA_INVALID_JSON, SCHEMA_DUPLICATE_KEY or
SCHEMA_NON_INTEGER_NUMBERpublic static byte[] canonicalBytes(byte[] data, CanonicalJson.Mode mode)
public static byte[] jcsBytes(Object value)
JCS mode).public static String jcsText(Object value)
jcsBytes(Object).public static byte[] documentBytes(Object value)
jcsBytes(canonicalizeDocument(value, true)): the canonical wire form of a lineage document.public static Object canonicalizeDocument(Object value, boolean strict)
canonicalizeDocument(value, strict, ArrayRegistry.standard(), null).public static Object canonicalizeDocument(Object value, boolean strict, ArrayRegistry registry, List<String> notes)
SET array sorted by its registered key; every
SEQUENCE and DISPLAY_ORDER array, and every array in open content, keeps its order.
Members keep their order (the writer orders them). Children are visited in input order and an array
is checked after its elements, as the reference does, so the first rejection is the reference's.strict - reject an unregistered array outside open content with SCHEMA_VIOLATION
(Section 5, rule 5); otherwise keep it in ordernotes - when not null and not strict, receives one line per unregistered array kept in orderSqllrException - SEMANTIC_ARRAY_KIND_VIOLATION for a SET holding two equal elements
or a SEQUENCE whose ordinals are not 0..n-1 (Section 5, rules 3 and 4);
SCHEMA_VIOLATION as abovepublic static Object immutableCopy(Object value)
public static int compareTyped(Object a, Object b)
null < false <
true < integers (numerically) < strings (unsigned UTF-8 bytes) < arrays and objects
(their canonical bytes, unsigned).public static int compareUnsigned(byte[] a, byte[] b)