+/**
+ * @see https://amzn.github.io/ion-docs/docs/spec.html#symbol ION spec's symbol definition
+ * @see https://amzn.github.io/ion-docs/guides/symbols-guide.html ION spec's symbol guide
+ */
+class Symbol {
+ /**
+ * Create an ION symbol.
+ */
+ public function __construct(
+ /**
+ * The symbol's text representation.
+ */
+ public readonly ?string $value = null,
+ /**
+ * The symbols ID, referencing its location within a shared symbol table.
+ */
+ public readonly int $sid = -1,
+ /**
+ * The import location referencing a shared symbol table.
+ */
+ public readonly ?Symbol\ImportLocation $importLocation = null,
+ ) {}
+
+ /**
+ * Compare two symbols for equality.
+ *
+ * Two symbols are considered equal, if either:
+ * * both are the same object or NULL
+ * * both values are NULL (unknown text), and both $importLocations match
+ * * both values match, regardless of $sid and $importLocation
+ *
+ * @param Symbol $symbol
+ * @return bool whether the two Symbols equal
+ */
+ public function equals(Symbol $symbol): bool {}
+ public function __toString() : string {}
+ /** @alias ion\Symbol::__toString */
+ public function toString() : string {}
+}
+
+/**
+ * The Catalog holds a collection of ion\Symbol\Table instances queried from ion\Reader and ion\Writer instances.
+ *
+ * @see https://amzn.github.io/ion-docs/docs/symbols.html#the-catalog the ION spec's symbol guide chapter on catalog.
+ */
+class Catalog implements \Countable {
+ /** Internal cache. */
+ private array $symbolTables = [];
+
+ /** Create a new Catalog. */
+ public function __construct() {}
+
+ /** Count how many symbol tables the catalog holds. */
+ public function count() : int {}
+
+ /**
+ * Add a shared symbol table to the catalog.
+ *
+ * @param Symbol\Table $table The new table to add.
+ */
+ public function add(Symbol\Table $table) : void {}
+
+ /**
+ * Remove a shared symbol table from the catalog.
+ *
+ * @param Symbol\Table|string $table The symbol table to renmove.
+ * @return bool Success.
+ */
+ public function remove(Symbol\Table|string $table) : bool {}
+
+ /**
+ * Find a shared symbol table within the catalog.
+ *
+ * @param string $name The name of the symbol table.
+ * @param int $version The version the symbol table should match.
+ * @return Symbol\Table|null The symbol table found, if any.
+ */
+ public function find(string $name, int $version = 0) : ?Symbol\Table {}
+
+ /**
+ * Find a "best match" for a shared symbol table within the catalog.
+ *
+ * @param string $name The name of the symbol table,
+ * @param int $version The minimum version of the symbol table.
+ * @return Symbol\Table|null The symbol table found, if any.
+ */
+ public function findBest(string $name, int $version = 0) : ?Symbol\Table {}
+}
+
+/**
+ * A large object.
+ *
+ * @see ion\Type
+ * @see https://amzn.github.io/ion-docs/docs/spec.html#blob the ION spec's BLob definition
+ * @see https://amzn.github.io/ion-docs/docs/spec.html#clob the ION sepc's CLob definition
+ */
+class LOB {
+ /**
+ * Create an ION large object.
+ */
+ public function __construct(
+ /**
+ * The value of the large object.
+ */
+ public readonly string $value,
+ /**
+ * The type (CLob/BLob).
+ */
+ public readonly Type $type = Type::CLob,
+ ) {}
+}
+
+/**
+ * An arbitrary precision fixed point decimal.
+ *
+ * @see ion\Decimal\Context
+ * @see https://amzn.github.io/ion-docs/docs/decimal.html the ION spec's decimal docs
+ */
+class Decimal {
+ /**
+ * Create a new fixed point decimal.
+ */
+ public function __construct(
+ /**
+ * The decimal number.
+ */
+ public readonly string|int $number,
+ /**
+ * The decimal context.
+ */
+ public readonly ?Decimal\Context $context = null,
+ ) {}
+
+ /**
+ * Check two decimals for equality.
+ *
+ * @param Decimal $decimal The decimal to compare to.
+ * @return bool Whether both decimals equal.
+ */
+ public function equals(Decimal $decimal) : bool {}
+
+ /**
+ * Check whether the decimal is actually a big integer.
+ * @return bool Whether the decimal is actually an integer.
+ */
+ public function isInt() : bool {}
+
+ public function __toString() : string {}
+ /**
+ * Get the string representation of the decimal.
+ * @alias ion\Decimal::__toString
+ */
+ public function toString() : string {}
+
+ /**
+ * Get the integer represention of the decimal.
+ * @throws \ion\Exception If the decimal is actually not an integer.
+ */
+ public function toInt() : int {}
+}
+
+/**
+ * An ION Timestamp.
+ * @see https://amzn.github.io/ion-docs/docs/spec.html#timestamp the ION spec's timestamp definition
+ * @see https://php.net/date PHP's date documentation
+ */
+class Timestamp extends \DateTime {
+ /**
+ * The timestamp's precision. See ion\Timestamp\Precision.
+ */
+ public readonly int $precision;
+ /**
+ * The timestamp's format. See ion\Timestamp\Format.
+ */
+ public readonly string $format;
+
+ /**
+ * Create a new ION timestamp.
+ *
+ * @param Timestamp\Precision|int $precision The timestamp's precision.
+ * @param Timestamp\Format|string|null $format The timestamp's format.
+ * @param string|null $datetime The timestamp's value.
+ * @param \DateTimeZone|string|null $timezone The timestamp's timezone.
+ */
+ public function __construct(
+ Timestamp\Precision|int $precision,
+ Timestamp\Format|string|null $format = null,
+ ?string $datetime = null,
+ \DateTimeZone|string|null $timezone = null,
+ ) {}
+
+ public function __toString() : string {}
+}
+
+/**
+ * ION reader API.
+ */
+interface Reader extends \RecursiveIterator {
+ public function getType() : Type;
+ public function hasAnnotations() : bool;
+ public function hasAnnotation(string $annotation) : bool;
+ public function isNull() : bool;
+ public function isInStruct() : bool;
+ public function getFieldName() : string;
+ public function getFieldNameSymbol() : Symbol;
+ public function getAnnotations() : array;
+ public function getAnnotationSymbols() : array;
+ public function countAnnotations() : int;
+ public function getAnnotation(int $index) : string;
+ public function getAnnotationSymbol(int $index) : Symbol;
+
+ public function readNull() : Type;
+ public function readBool() : bool;
+ public function readInt() : int|string;
+ public function readFloat() : float;
+ public function readDecimal() : Decimal;
+ public function readTimestamp() : Timestamp;
+ public function readSymbol() : Symbol;
+ public function readString() : string;
+ /** @param ref $string */
+ public function readStringPart(&$string, int $length = 0x1000) : bool;
+ public function readLob() : string;
+ /** @param ref $string */
+ public function readLobPart(&$string, int $length = 0x1000) : bool;
+
+ public function getPosition() : int;
+ public function getDepth() : int;
+
+ public function seek(int $offset, int $length = -1) : void;
+ /*
+ public function getSymbolTable() : SymbolTable;
+ public function setSymbolTable(SymbolTable $table) : void;
+ */
+ public function getValueOffset() : int;
+ public function getValueLength() : int;
+}
+
+/**
+ * ION writer API.
+ */
+interface Writer {
+ public function writeNull() : void;
+ public function writeTypedNull(Type $type) : void;
+ public function writeBool(bool $value) : void;
+ public function writeInt(int|string $value) : void;
+ public function writeFloat(float $value) : void;
+ public function writeDecimal(Decimal|string $value) : void;
+ public function writeTimestamp(Timestamp|string $value) : void;
+ public function writeSymbol(Symbol|string $value) : void;
+ public function writeString(string $value) : void;
+ public function writeCLob(string $value) : void;
+ public function writeBLob(string $value) : void;
+
+ public function startLob(Type $type) : void;
+ public function appendLob(string $data) : void;
+ public function finishLob() : void;
+
+ public function startContainer(Type $type) : void;
+ public function finishContainer() : void;
+
+ public function writeFieldName(string $name) : void;
+
+ public function writeAnnotation(Symbol|string ...$annotation) : void;
+
+ public function getDepth() : int;
+ public function flush() : int;
+ public function finish() : int;
+
+ // public function writeOne(Reader $reader) : void;
+ // public function writeAll(Reader $reader) : void;
+
+ // public function getCatalog() : Catalog;
+ // public function setCatalog(Catalog $catalog) : void;
+
+ // public function getSymbolTable() : Symbol\Table;
+ // puvlic function setSymbolTable(Symbol\Table $table) : void;
+}
+