@foxglove/omgidl-parser
Version:
Parse OMG IDL to flattened definitions for serialization
68 lines (59 loc) • 2.56 kB
text/typescript
import { ConstantValue } from "@foxglove/message-definition";
import { EnumIDLNode } from "./EnumIDLNode";
import { IDLNode } from "./IDLNode";
import { AnyIDLNode, IConstantIDLNode } from "./interfaces";
import { ConstantASTNode } from "../astTypes";
import { SIMPLE_TYPES, normalizeType } from "../primitiveTypes";
import { IDLMessageDefinitionField } from "../types";
/** Wraps constant node so that its type and value can be resolved and written to a message definition */
export class ConstantIDLNode extends IDLNode<ConstantASTNode> implements IConstantIDLNode {
/** If the type needs resolution (not simple primitive) this will be set to true. Should only ever mean that it's referencing an enum */
private typeNeedsResolution = false;
constructor(scopePath: string[], astNode: ConstantASTNode, idlMap: Map<string, AnyIDLNode>) {
super(scopePath, astNode, idlMap);
if (!SIMPLE_TYPES.has(astNode.type)) {
this.typeNeedsResolution = true;
}
}
get type(): string {
if (this.typeNeedsResolution) {
return this.getReferencedEnumNode().type;
}
return this.astNode.type;
}
/** Holds reference so that it doesn't need to be searched for again */
private referencedEnumNode?: EnumIDLNode = undefined;
/** Gets enum node referenced by type. Fails otherwise. */
private getReferencedEnumNode(): EnumIDLNode {
if (this.referencedEnumNode == undefined) {
const maybeEnumNode = this.getNode(this.scopePath, this.astNode.type);
if (!(maybeEnumNode instanceof EnumIDLNode)) {
throw new Error(`Expected ${this.astNode.type} to be an enum in ${this.scopedIdentifier}`);
}
this.referencedEnumNode = maybeEnumNode;
}
return this.referencedEnumNode;
}
// eslint-disable-next-line @typescript-eslint/class-literal-property-style
get isConstant(): true {
return true;
}
/** Return Literal value on astNode or if the constant references another constant, then it gets the value that constant uses */
get value(): ConstantValue {
if (typeof this.astNode.value === "object") {
return this.getConstantNode(this.astNode.value.name).value;
}
return this.astNode.value;
}
/** Writes resolved IDLMessageDefinition */
toIDLMessageDefinitionField(): IDLMessageDefinitionField {
return {
name: this.name,
type: normalizeType(this.type),
value: this.value,
isConstant: true,
isComplex: false,
...(this.astNode.valueText != undefined ? { valueText: this.astNode.valueText } : undefined),
};
}
}