Skip to content

Commit

Permalink
adds read support for local symbol table append (#760)
Browse files Browse the repository at this point in the history
  • Loading branch information
desaikd committed Jul 11, 2023
1 parent 8bb0cb2 commit 14b0bab
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/IonBinaryReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class BinaryReader implements Reader {
if (this._parser.getAnnotation(0) !== ion_symbol_table_sid) {
break;
}
this._symtab = makeSymbolTable(this._cat, this);
this._symtab = makeSymbolTable(this._cat, this, this._symtab);
} else {
break;
}
Expand Down
31 changes: 28 additions & 3 deletions src/IonSymbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Reader } from "./IonReader";
import { SharedSymbolTable } from "./IonSharedSymbolTable";
import { SubstituteSymbolTable } from "./IonSubstituteSymbolTable";
import { getSystemSymbolTableImport } from "./IonSystemSymbolTable";
import { IonTypes } from "./Ion";

export const ion_symbol_table = "$ion_symbol_table";
export const ion_symbol_table_sid = 3;
Expand Down Expand Up @@ -100,15 +101,18 @@ function load_symbols(reader: Reader): (string | null)[] {
*
* @param catalog The catalog to resolve imported shared symbol tables from.
* @param reader The Ion {Reader} over the local symbol table in its serialized form.
* @param currentSymbolTable Current local symbol table for the reader.
*/
export function makeSymbolTable(
catalog: Catalog,
reader: Reader
reader: Reader,
currentSymbolTable: LocalSymbolTable
): LocalSymbolTable {
let import_: Import | null = null;
let symbols: (string | null)[] = [];
let foundSymbols: boolean = false;
let foundImports: boolean = false;
let foundLstAppend: boolean = false;

reader.stepIn();
while (reader.next()) {
Expand All @@ -117,14 +121,35 @@ export function makeSymbolTable(
if (foundImports) {
throw new Error("Multiple import fields found.");
}
import_ = load_imports(reader, catalog);
let ion_type = reader.type();
if (
ion_type === IonTypes.SYMBOL &&
reader.stringValue() === ion_symbol_table
) {
// this is a local symbol table append
import_ = currentSymbolTable.import;
let symbols_ = symbols;
symbols = currentSymbolTable.symbols;
symbols.push(...symbols_);
foundLstAppend = true;
} else if (ion_type === IonTypes.LIST) {
import_ = load_imports(reader, catalog);
} else {
throw new Error(
`Expected import field name to be a list or symbol found ${ion_type}`
);
}
foundImports = true;
break;
case "symbols":
if (foundSymbols) {
throw new Error("Multiple symbol fields found.");
}
symbols = load_symbols(reader);
if (foundLstAppend) {
symbols.push(...load_symbols(reader));
} else {
symbols = load_symbols(reader);
}
foundSymbols = true;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/IonTextReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class TextReader implements Reader {
break;
}
this._type = get_ion_type(this._raw_type);
this._symtab = makeSymbolTable(this._cat, this);
this._symtab = makeSymbolTable(this._cat, this, this._symtab);
this._raw = undefined;
this._raw_type = undefined;
} else {
Expand Down
13 changes: 13 additions & 0 deletions test/IonTextReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ class IonTextReaderTests {
assert.equal(ionReader.stringValue(), 'taco');
}

@test "resolves symbol IDs for symbol table append"() {
let ionToRead = `$ion_symbol_table::{ symbols:[ "foo", "bar" ]} $ion_symbol_table::{ imports: $ion_symbol_table, symbols:[ "baz" ]}[$10, $11, $12]`;
let ionReader = ion.makeReader(ionToRead);
ionReader.next();
ionReader.stepIn();
ionReader.next();
assert.equal(ionReader.stringValue(), "foo");
ionReader.next();
assert.equal(ionReader.stringValue(), "bar");
ionReader.next();
assert.equal(ionReader.stringValue(), "baz");
}

@test "Parse through struct"() {
let ionToRead = "{ key : \"string\" }";
let ionReader = ion.makeReader(ionToRead);
Expand Down
1 change: 0 additions & 1 deletion test/iontests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@ let equivsSkipList = toSkipList([
"ion-tests/iontestdata/good/equivs/decimalsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/floatsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/intsWithUnderscores.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTableAppend.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTableNullSlots.ion",
"ion-tests/iontestdata/good/equivs/localSymbolTables.ion",
"ion-tests/iontestdata/good/equivs/nonIVMNoOps.ion",
Expand Down

0 comments on commit 14b0bab

Please sign in to comment.