UNPKG

@cosmology/ast

Version:
184 lines (183 loc) 6.14 kB
import { isRefExcluded, getObjectName } from '@cosmology/utils'; import { getEnumFromJsonName, getEnumToJsonName, getFieldsTypeName } from './proto'; import { getPluginValue } from '../plugins'; export class GenericParseContext { options; imports = []; derivedImports = []; utils = {}; store; ref; constructor(ref, store, options) { this.ref = ref; this.store = store; this.options = options; if (!this.options) { throw new Error('ParseContext requires options!'); } } pluginValue(name) { return getPluginValue(name, this.ref?.proto?.package, this.options); } isExcluded() { const excluded = this.pluginValue('prototypes.excluded'); return isRefExcluded(this.ref, excluded); } addUtil(util) { this.utils[util] = true; } addImport(imp) { // some local lookups don't have an import (local proto-style lookups do) if (!imp.import) return; this.imports.push(imp); } addImportDerivative(imp) { const found = this.derivedImports.find(a => { return a.type === imp.type && a.symbol.symbolName === imp.symbol.symbolName && a.symbol.source === imp.symbol.source; }); if (!found) { this.derivedImports.push(imp); } } getTypeNameFromFieldName(name, importSrc) { let importedAs = name; const names = this.ref.traversed?.importNames; if (names && names.hasOwnProperty(importSrc) && names[importSrc].hasOwnProperty(name)) { importedAs = names[importSrc][name]; } this.addImport({ type: 'typeImport', name, importedAs, import: importSrc }); return importedAs; } getTypeName(field) { let name = getFieldsTypeName(field); return this.getTypeNameFromFieldName(name, field.import); } lookupTypeFromCurrentPath(field, currentProtoPath) { const ref = this.store.findProto(currentProtoPath); let lookup = this.store.get(ref, field.parsedType.name); if (!lookup) { // if we can't find it, use field import if (field.import) { const importRef = this.store.findProto(field.import); if (!importRef) { throw new Error(`bad import ${field.import}`); } lookup = this.store.get(importRef, field.parsedType.name); } if (!lookup) { throw new Error('Undefined Symbol: ' + field.parsedType.name); } } return lookup; } getTypeFromCurrentPath(field, currentProtoPath) { const ref = this.store.findProto(currentProtoPath); let lookup = this.store.get(ref, field.parsedType.name); if (!lookup) { // if we can't find it, use field import if (field.import) { const importRef = this.store.findProto(field.import); if (!importRef) { throw new Error(`bad import ${field.import}`); } lookup = this.store.get(importRef, field.parsedType.name); } if (!lookup) { throw new Error('Undefined Symbol: ' + field.parsedType.name); } } this.addImport({ type: 'typeImport', name: lookup.importedName, import: lookup.import }); return lookup.obj; } } export class AminoParseContext extends GenericParseContext { aminoCasingFn; constructor(ref, store, options) { super(ref, store, options); this.ref = ref; this.store = store; this.options = options; this.setAminoCasingFn(); if (!this.aminoCasingFn) { throw new Error('missing aminoCasingFn!'); } this.aminoCaseField = this.aminoCaseField.bind(this); } setAminoCasingFn() { if (this.aminoCasingFn) return this.aminoCasingFn; this.aminoCasingFn = this.pluginValue('aminoEncoding.casingFn'); return this.aminoCasingFn; } aminoCaseField(field) { return field.options['(telescope:orig)']; } lookupEnumFromJson(field, currentProtoPath) { const lookup = this.lookupTypeFromCurrentPath(field, currentProtoPath); const Enum = lookup.obj; const name = getEnumFromJsonName(getObjectName(Enum.name, Enum.scope)); this.addImport({ type: 'fromJSONEnum', name, import: lookup.import }); return name; } lookupEnumToJson(field, currentProtoPath) { const lookup = this.lookupTypeFromCurrentPath(field, currentProtoPath); const Enum = lookup.obj; const name = getEnumToJsonName(getObjectName(Enum.name, Enum.scope)); this.addImport({ type: 'toJSONEnum', name, import: lookup.import }); return name; } } export class ProtoParseContext extends GenericParseContext { constructor(ref, store, options) { super(ref, store, options); this.ref = ref; this.store = store; this.options = options; } setEnumValues(pkg, name, protoSyntex, values) { this.store.setEnumValues(pkg, name, protoSyntex, values); } getDefaultOrExistingSmallestEnumValue(pkg, name) { return this.store.getDefaultOrExistingSmallestEnumValue(pkg, name); } getToEnum(field) { const name = getEnumToJsonName(getFieldsTypeName(field)); this.addImport({ type: 'toJSONEnum', name, import: field.import }); return name; } getFromEnum(field) { const fromJSONFuncName = getEnumFromJsonName(getFieldsTypeName(field)); this.addImport({ type: 'fromJSONEnum', name: fromJSONFuncName, import: field.import }); return fromJSONFuncName; } }