// Copyright 2021 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { SyntaxNode } from '@lezer/common'; import { AggregateExpr, AnchoredExpr, BinaryExpr, FunctionCall, MatrixSelector, NumberDurationLiteral, OffsetExpr, ParenExpr, SmoothedExpr, StepInvariantExpr, StringLiteral, SubqueryExpr, UnaryExpr, VectorSelector, } from '@prometheus-io/lezer-promql'; import { getFunction, ValueType } from '../types'; // Based on https://github.com/prometheus/prometheus/blob/d668a7efe3107dbdcc67bf4e9f12430ed8e2b396/promql/parser/ast.go#L191 export function getType(node: SyntaxNode | null): ValueType { if (!node) { return ValueType.none; } switch (node.type.id) { case AggregateExpr: return ValueType.vector; case VectorSelector: return ValueType.vector; case OffsetExpr: return getType(node.firstChild); case StringLiteral: return ValueType.string; case NumberDurationLiteral: return ValueType.scalar; case MatrixSelector: return ValueType.matrix; case SubqueryExpr: return ValueType.matrix; case SmoothedExpr: return getType(node.firstChild); case AnchoredExpr: return getType(node.firstChild); case ParenExpr: return getType(node.getChild('Expr')); case UnaryExpr: return getType(node.getChild('Expr')); case BinaryExpr: { const lt = getType(node.firstChild); const rt = getType(node.lastChild); if (lt === ValueType.scalar && rt === ValueType.scalar) { return ValueType.scalar; } return ValueType.vector; } case FunctionCall: { const funcNode = node.firstChild?.firstChild; if (!funcNode) { return ValueType.none; } return getFunction(funcNode.type.id).returnType; } case StepInvariantExpr: return getType(node.getChild('Expr')); default: return ValueType.none; } }