Skip to content

Commit

Permalink
Refactor schema loader
Browse files Browse the repository at this point in the history
  • Loading branch information
davelopez committed Sep 4, 2022
1 parent bbce6c8 commit df74ec5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 48 deletions.
5 changes: 2 additions & 3 deletions server/gx-workflow-ls-format2/src/schema/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ export class RecordSchemaNode implements SchemaNode {
}

export interface SchemaDefinitions {
types: Map<string, SchemaEntry>;
records: Map<string, SchemaRecord>;
fields: Map<string, SchemaField>;
records: Map<string, RecordSchemaNode>;
fields: Map<string, FieldSchemaNode>;
specializations: Map<string, string>;
}
87 changes: 49 additions & 38 deletions server/gx-workflow-ls-format2/src/schema/schemaLoader.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
FieldSchemaNode,
isSchemaEntryBase,
isSchemaRecord,
RecordSchemaNode,
SchemaDefinitions,
SchemaDocument,
SchemaEntry,
Expand All @@ -13,16 +15,18 @@ import { SchemaNodeResolver } from "./schemaNodeResolver";
import { SCHEMA_DOCS_v19_09_MAP } from "./versions";

export class GalaxyWorkflowFormat2SchemaLoader {
public readonly definitions: SchemaDefinitions;
private _documentTypeMap = new Map<string, Map<string, SchemaEntry>>();
private _documentEntryMap = new Map<string, Map<string, SchemaEntry>>();
private _rawSchemaEntries = new Map<string, SchemaEntry>();
private _namespaces = new Map<string, string>();
public readonly nodeResolver: SchemaNodeResolver;

private _unknownTypes: string[] = [];
private _extendedTypes: Set<string> = new Set();
private _root?: SchemaRecord;
public readonly definitions: SchemaDefinitions;
public readonly nodeResolver: SchemaNodeResolver;

constructor(private readonly enableDebugTrace: boolean = false) {
this.definitions = this.loadSchemaDefinitions_v19_09();
this._rawSchemaEntries = this.loadSchemaEntriesMap_v19_09();
this.definitions = this.loadSchemaDefinitions(this._rawSchemaEntries);
this.nodeResolver = this.createNodeResolver();

if (this.enableDebugTrace) {
Expand All @@ -36,40 +40,48 @@ export class GalaxyWorkflowFormat2SchemaLoader {
if (this._extendedTypes) {
console.debug(`EXTENDED Types (Unresolved): ${this._extendedTypes.size}`);
this._extendedTypes.forEach((type) => {
if (!this.definitions.types.has(type)) {
console.debug(` ${type} ${this.definitions.types.has(type) ? "[found]" : ""}`);
if (!this._rawSchemaEntries.has(type)) {
console.debug(` ${type} ${this._rawSchemaEntries.has(type) ? "[found]" : ""}`);
}
});
}
}
}

private loadSchemaDefinitions_v19_09(): SchemaDefinitions {
private loadSchemaEntriesMap_v19_09(): Map<string, SchemaEntry> {
const entries = new Map<string, SchemaEntry>();
for (const schemaDoc of SCHEMA_DOCS_v19_09_MAP.values()) {
const types = this.loadSchemaDocument(schemaDoc);
types.forEach((v, k) => {
entries.set(k, v);
});
}
return entries;
}

private loadSchemaDefinitions(schemaEntries: Map<string, SchemaEntry>): SchemaDefinitions {
const definitions: SchemaDefinitions = {
types: new Map<string, SchemaEntry>(),
records: new Map<string, SchemaRecord>(),
fields: new Map<string, SchemaField>(),
records: new Map<string, RecordSchemaNode>(),
fields: new Map<string, FieldSchemaNode>(),
specializations: new Map<string, string>(),
};
SCHEMA_DOCS_v19_09_MAP.forEach((schemaDoc) => {
const types = this.loadSchemaDocument(schemaDoc);
types.forEach((v, k) => {
definitions.types.set(k, v);
if (isSchemaRecord(v)) {
definitions.records.set(k, v);
if (v.specialize) {
v.specialize.forEach((sp) => {
definitions.specializations.set(sp.specializeFrom, sp.specializeTo);
});
}
v.fields.forEach((field) => {
if (definitions.fields.has(field.name)) {
if (this.enableDebugTrace) console.debug("****** DUPLICATED FIELD", field.name);
}
definitions.fields.set(field.name, field);

this.expandRecords(schemaEntries.values());
schemaEntries.forEach((v, k) => {
if (isSchemaRecord(v)) {
definitions.records.set(k, new RecordSchemaNode(v));
if (v.specialize) {
v.specialize.forEach((sp) => {
definitions.specializations.set(sp.specializeFrom, sp.specializeTo);
});
}
});
v.fields.forEach((field) => {
if (definitions.fields.has(field.name)) {
if (this.enableDebugTrace) console.debug("****** DUPLICATED FIELD", field.name);
}
definitions.fields.set(field.name, new FieldSchemaNode(field));
});
}
});
return definitions;
}
Expand All @@ -95,7 +107,7 @@ export class GalaxyWorkflowFormat2SchemaLoader {
documentEntries.set(entry.name, loadedEntry);
}
});
this._documentTypeMap.set(schemaDoc.$base, documentEntries);
this._documentEntryMap.set(schemaDoc.$base, documentEntries);
return documentEntries;
}

Expand Down Expand Up @@ -208,7 +220,7 @@ export class GalaxyWorkflowFormat2SchemaLoader {
if (namespace && type) {
const docBase = this._namespaces.get(namespace);
if (docBase) {
const schemaTypes = this._documentTypeMap.get(docBase);
const schemaTypes = this._documentEntryMap.get(docBase);
if (schemaTypes?.has(type)) {
rawTypeName = type;
} else {
Expand All @@ -224,24 +236,23 @@ export class GalaxyWorkflowFormat2SchemaLoader {

private resolveTypeToSchemaEntry(rawTypeName: string): SchemaEntry {
const typeName = this.resolveTypeName(rawTypeName);
if (this.definitions.types.has(typeName)) {
return this.definitions.types.get(typeName) as SchemaEntry;
if (this._rawSchemaEntries.has(typeName)) {
return this._rawSchemaEntries.get(typeName) as SchemaEntry;
}
throw new Error(`Unresolvable type ${rawTypeName}`);
}

private createNodeResolver(): SchemaNodeResolver {
this.expandRecords();
return new SchemaNodeResolver(this.definitions, this._root);
}

/** Expands all records with the fields defined in the extended types.*/
private expandRecords(): void {
this.definitions.types.forEach((value: SchemaEntry) => {
if (isSchemaRecord(value)) {
this.expandRecord(value);
private expandRecords(schemaEntries: IterableIterator<SchemaEntry>): void {
for (const entry of schemaEntries) {
if (isSchemaRecord(entry)) {
this.expandRecord(entry);
}
});
}
}

private expandRecord(record: SchemaRecord): SchemaRecord {
Expand Down
10 changes: 3 additions & 7 deletions server/gx-workflow-ls-format2/src/schema/schemaNodeResolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NodePath, Segment } from "@gxwf/server-common/src/ast/types";
import { SchemaDefinitions, SchemaNode, RecordSchemaNode, FieldSchemaNode, SchemaRecord } from "./definitions";
import { SchemaDefinitions, SchemaNode, RecordSchemaNode, SchemaRecord } from "./definitions";

export class SchemaNodeResolver {
public readonly rootNode: SchemaNode;
Expand Down Expand Up @@ -29,13 +29,9 @@ export class SchemaNodeResolver {
if (typeof pathSegment === "string") {
pathSegment = this.definitions.specializations.get(pathSegment) || pathSegment;
if (this.definitions.records.has(pathSegment)) {
const record = this.definitions.records.get(pathSegment);
if (record) return new RecordSchemaNode(record);
}
if (this.definitions.fields.has(pathSegment)) {
const field = this.definitions.fields.get(pathSegment);
if (field) return new FieldSchemaNode(field);
return this.definitions.records.get(pathSegment);
}
return this.definitions.fields.get(pathSegment);
}
return undefined;
}
Expand Down

0 comments on commit df74ec5

Please sign in to comment.