{"version":3,"file":"situation.mjs","sources":["../../../../../src/components/monaco-query-field/monaco-completion-provider/situation.ts"],"sourcesContent":["// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/situation.ts\nimport type { SyntaxNode, Tree } from '@lezer/common';\nimport {\n  AggregateExpr,\n  AggregateModifier,\n  BinaryExpr,\n  EqlRegex,\n  EqlSingle,\n  FunctionCallBody,\n  GroupingLabels,\n  Identifier,\n  LabelMatchers,\n  LabelName,\n  MatchOp,\n  MatrixSelector,\n  Neq,\n  NeqRegex,\n  NumberDurationLiteralInDurationContext,\n  parser,\n  PromQL,\n  QuotedLabelMatcher,\n  QuotedLabelName,\n  StringLiteral,\n  UnquotedLabelMatcher,\n  VectorSelector,\n} from '@prometheus-io/lezer-promql';\n\nimport { NeverCaseError } from './util';\n\ntype Direction = 'parent' | 'firstChild' | 'lastChild' | 'nextSibling';\n\ntype NodeTypeId =\n  | 0 // this is used as error-id\n  | typeof AggregateExpr\n  | typeof AggregateModifier\n  | typeof FunctionCallBody\n  | typeof GroupingLabels\n  | typeof Identifier\n  | typeof UnquotedLabelMatcher\n  | typeof QuotedLabelMatcher\n  | typeof LabelMatchers\n  | typeof LabelName\n  | typeof QuotedLabelName\n  | typeof PromQL\n  | typeof StringLiteral\n  | typeof VectorSelector\n  | typeof MatrixSelector\n  | typeof MatchOp\n  | typeof EqlSingle\n  | typeof Neq\n  | typeof EqlRegex\n  | typeof NeqRegex;\n\ntype Path = Array<[Direction, NodeTypeId]>;\n\nfunction move(node: SyntaxNode, direction: Direction): SyntaxNode | null {\n  switch (direction) {\n    case 'parent':\n      return node.parent;\n    case 'firstChild':\n      return node.firstChild;\n    case 'lastChild':\n      return node.lastChild;\n    case 'nextSibling':\n      return node.nextSibling;\n    default:\n      throw new NeverCaseError(direction);\n  }\n}\n\nfunction walk(node: SyntaxNode, path: Path): SyntaxNode | null {\n  let current: SyntaxNode | null = node;\n  for (const [direction, expectedType] of path) {\n    current = move(current, direction);\n    if (current === null) {\n      // we could not move in the direction, we stop\n      return null;\n    }\n    if (current.type.id !== expectedType) {\n      // the reached node has wrong type, we stop\n      return null;\n    }\n  }\n  return current;\n}\n\nfunction getNodeText(node: SyntaxNode, text: string, utf8?: boolean): string {\n  const nodeFrom = utf8 ? node.from + 1 : node.from;\n  const nodeTo = utf8 ? node.to - 1 : node.to;\n  return text.slice(nodeFrom, nodeTo);\n}\n\nfunction parsePromQLStringLiteral(text: string): string {\n  // if it is a string-literal, it is inside quotes of some kind\n  const inside = text.slice(1, text.length - 1);\n\n  // FIXME: support https://prometheus.io/docs/prometheus/latest/querying/basics/#string-literals\n  // FIXME: maybe check other promql code, if all is supported or not\n\n  // for now we do only some very simple un-escaping\n\n  // we start with double-quotes\n  if (text.startsWith('\"') && text.endsWith('\"')) {\n    // NOTE: this is not 100% perfect, we only unescape the double-quote,\n    // there might be other characters too\n    return inside.replace(/\\\\\"/, '\"');\n  }\n\n  // then single-quote\n  if (text.startsWith(\"'\") && text.endsWith(\"'\")) {\n    // NOTE: this is not 100% perfect, we only unescape the single-quote,\n    // there might be other characters too\n    return inside.replace(/\\\\'/, \"'\");\n  }\n\n  // then backticks\n  if (text.startsWith('`') && text.endsWith('`')) {\n    return inside;\n  }\n\n  throw new Error('FIXME: invalid string literal');\n}\n\ntype LabelOperator = '=' | '!=' | '=~' | '!~';\n\nexport type Label = {\n  name: string;\n  value: string;\n  op: LabelOperator;\n};\n\nexport type Situation =\n  | {\n      type: 'IN_FUNCTION';\n    }\n  | {\n      type: 'AT_ROOT';\n    }\n  | {\n      type: 'EMPTY';\n    }\n  | {\n      type: 'IN_DURATION';\n    }\n  | {\n      type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME';\n      metricName?: string;\n      otherLabels: Label[];\n      // utf8 labels must be in quotes\n      betweenQuotes: boolean;\n    }\n  | {\n      type: 'IN_GROUPING';\n      metricName: string;\n      otherLabels: Label[];\n    }\n  | {\n      type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME';\n      metricName?: string;\n      labelName: string;\n      betweenQuotes: boolean;\n      otherLabels: Label[];\n    };\n\ntype Resolver = {\n  path: NodeTypeId[];\n  fun: (node: SyntaxNode, text: string, pos: number) => Situation | null;\n};\n\nfunction isPathMatch(resolverPath: NodeTypeId[], cursorPath: number[]): boolean {\n  return resolverPath.every((item, index) => item === cursorPath[index]);\n}\n\nconst ERROR_NODE_NAME: NodeTypeId = 0; // this is used as error-id\n\nconst RESOLVERS: Resolver[] = [\n  {\n    path: [LabelMatchers, VectorSelector],\n    fun: resolveLabelKeysWithEquals,\n  },\n  {\n    path: [StringLiteral, QuotedLabelName, LabelMatchers, VectorSelector],\n    fun: resolveUtf8LabelKeysWithEquals,\n  },\n  {\n    path: [PromQL],\n    fun: resolveTopLevel,\n  },\n  {\n    // Partially written metric name\n    path: [Identifier, VectorSelector, PromQL],\n    fun: resolveTopLevel,\n  },\n  {\n    path: [FunctionCallBody],\n    fun: resolveInFunction,\n  },\n  {\n    path: [StringLiteral, UnquotedLabelMatcher],\n    fun: resolveLabelMatcher,\n  },\n  {\n    path: [StringLiteral, QuotedLabelMatcher],\n    fun: resolveQuotedLabelMatcher,\n  },\n  {\n    path: [ERROR_NODE_NAME, BinaryExpr, PromQL],\n    fun: resolveTopLevel,\n  },\n  {\n    path: [ERROR_NODE_NAME, UnquotedLabelMatcher],\n    fun: resolveLabelMatcher,\n  },\n  {\n    path: [ERROR_NODE_NAME, QuotedLabelMatcher],\n    fun: resolveQuotedLabelMatcher,\n  },\n  {\n    path: [ERROR_NODE_NAME, NumberDurationLiteralInDurationContext, MatrixSelector],\n    fun: resolveDurations,\n  },\n  {\n    path: [GroupingLabels],\n    fun: resolveLabelsForGrouping,\n  },\n];\n\nconst LABEL_OP_MAP = new Map<number, LabelOperator>([\n  [EqlSingle, '='],\n  [EqlRegex, '=~'],\n  [Neq, '!='],\n  [NeqRegex, '!~'],\n]);\n\nfunction getLabelOp(opNode: SyntaxNode): LabelOperator | null {\n  const opChild = opNode.firstChild;\n  if (opChild === null) {\n    return null;\n  }\n\n  return LABEL_OP_MAP.get(opChild.type.id) ?? null;\n}\n\nfunction getLabel(labelMatcherNode: SyntaxNode, text: string): Label | null {\n  const allowedMatchers = new Set([UnquotedLabelMatcher, QuotedLabelMatcher]);\n  if (!allowedMatchers.has(labelMatcherNode.type.id)) {\n    return null;\n  }\n\n  const nameNode =\n    walk(labelMatcherNode, [['firstChild', LabelName]]) ?? walk(labelMatcherNode, [['firstChild', QuotedLabelName]]);\n\n  if (nameNode === null) {\n    return null;\n  }\n\n  const opNode = walk(nameNode, [['nextSibling', MatchOp]]);\n  if (opNode === null) {\n    return null;\n  }\n\n  const op = getLabelOp(opNode);\n  if (op === null) {\n    return null;\n  }\n\n  const valueNode = walk(labelMatcherNode, [['lastChild', StringLiteral]]);\n\n  if (valueNode === null) {\n    return null;\n  }\n\n  const name = getNodeText(nameNode, text);\n  const value = parsePromQLStringLiteral(getNodeText(valueNode, text));\n\n  return { name, value, op };\n}\n\nfunction getLabels(labelMatchersNode: SyntaxNode, text: string): Label[] {\n  if (labelMatchersNode.type.id !== LabelMatchers) {\n    return [];\n  }\n\n  const matchers = [UnquotedLabelMatcher, QuotedLabelMatcher];\n\n  return matchers.reduce<Label[]>((acc, matcher) => {\n    labelMatchersNode.getChildren(matcher).forEach((ln) => {\n      const label = getLabel(ln, text);\n      if (notEmpty(label)) {\n        acc.push(label);\n      }\n    });\n    return acc;\n  }, []);\n}\n\nfunction getNodeChildren(node: SyntaxNode): SyntaxNode[] {\n  let child: SyntaxNode | null = node.firstChild;\n  const children: SyntaxNode[] = [];\n  while (child !== null) {\n    children.push(child);\n    child = child.nextSibling;\n  }\n  return children;\n}\n\nfunction getNodeInSubtree(node: SyntaxNode, typeId: NodeTypeId): SyntaxNode | null {\n  // first we try the current node\n  if (node.type.id === typeId) {\n    return node;\n  }\n\n  // then we try the children\n  const children = getNodeChildren(node);\n  for (const child of children) {\n    const n = getNodeInSubtree(child, typeId);\n    if (n !== null) {\n      return n;\n    }\n  }\n\n  return null;\n}\n\nfunction resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number): Situation | null {\n  const aggrExpNode = walk(node, [\n    ['parent', AggregateModifier],\n    ['parent', AggregateExpr],\n  ]);\n  if (aggrExpNode === null) {\n    return null;\n  }\n  const bodyNode = aggrExpNode.getChild(FunctionCallBody);\n  if (bodyNode === null) {\n    return null;\n  }\n\n  const metricIdNode = getNodeInSubtree(bodyNode, Identifier) ?? getNodeInSubtree(bodyNode, StringLiteral);\n\n  if (!metricIdNode) {\n    return null;\n  }\n\n  // Let's check whether it's a utf8 metric.\n  // A utf8 metric must be a StringLiteral and its parent must be a QuotedLabelName\n  if (metricIdNode.type.id === StringLiteral && metricIdNode.parent?.type.id !== QuotedLabelName) {\n    return null;\n  }\n\n  const metricName = getNodeText(metricIdNode, text, metricIdNode.type.id === StringLiteral);\n\n  return {\n    type: 'IN_GROUPING',\n    metricName,\n    otherLabels: [],\n  };\n}\n\nfunction resolveLabelMatcher(node: SyntaxNode, text: string, pos: number): Situation | null {\n  // we can arrive here in two situation. `node` is either:\n  // - a StringNode (like in `{job=\"^\"}`)\n  // - or an error node (like in `{job=^}`)\n  const inStringNode = !node.type.isError;\n\n  const parent = walk(node, [['parent', UnquotedLabelMatcher]]);\n  if (parent === null) {\n    return null;\n  }\n\n  const labelNameNode = walk(parent, [['firstChild', LabelName]]);\n  if (labelNameNode === null) {\n    return null;\n  }\n\n  const labelName = getNodeText(labelNameNode, text);\n\n  const labelMatchersNode = walk(parent, [['parent', LabelMatchers]]);\n  if (labelMatchersNode === null) {\n    return null;\n  }\n\n  // now we need to find the other names\n  const allLabels = getLabels(labelMatchersNode, text);\n\n  // we need to remove \"our\" label from all-labels, if it is in there\n  const otherLabels = allLabels.filter((label) => label.name !== labelName);\n\n  const metricName = getMetricName(labelMatchersNode, text);\n\n  // we are probably in a situation without a metric name\n  return {\n    type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',\n    labelName,\n    betweenQuotes: inStringNode,\n    otherLabels,\n    ...(metricName ? { metricName } : {}),\n  };\n}\n\nfunction resolveQuotedLabelMatcher(node: SyntaxNode, text: string, pos: number): Situation | null {\n  // we can arrive here in two situation. `node` is either:\n  // - a StringNode (like in `{\"job\"=\"^\"}`)\n  // - or an error node (like in `{\"job\"=^}`)\n  const inStringNode = !node.type.isError;\n\n  const parent = walk(node, [['parent', QuotedLabelMatcher]]);\n  if (parent === null) {\n    return null;\n  }\n\n  const labelNameNode = walk(parent, [['firstChild', QuotedLabelName]]);\n  if (labelNameNode === null) {\n    return null;\n  }\n\n  const labelName = getNodeText(labelNameNode, text);\n\n  const labelMatchersNode = walk(parent, [['parent', LabelMatchers]]);\n  if (labelMatchersNode === null) {\n    return null;\n  }\n\n  // now we need to find the other names\n  const allLabels = getLabels(labelMatchersNode, text);\n\n  // we need to remove \"our\" label from all-labels, if it is in there\n  const otherLabels = allLabels.filter((label) => label.name !== labelName);\n  const metricName = getMetricName(parent.parent!, text);\n\n  return {\n    type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',\n    labelName,\n    betweenQuotes: inStringNode,\n    otherLabels,\n    ...(metricName ? { metricName } : {}),\n  };\n}\n\nfunction resolveTopLevel(node: SyntaxNode, text: string, pos: number): Situation {\n  return {\n    type: 'AT_ROOT',\n  };\n}\n\nfunction resolveInFunction(node: SyntaxNode, text: string, pos: number): Situation {\n  return {\n    type: 'IN_FUNCTION',\n  };\n}\n\nfunction resolveDurations(node: SyntaxNode, text: string, pos: number): Situation {\n  return {\n    type: 'IN_DURATION',\n  };\n}\n\nfunction resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {\n  // next false positive:\n  // `something{a=\"1\"^}`\n  let child = walk(node, [['firstChild', UnquotedLabelMatcher]]);\n  if (child !== null) {\n    // means the label-matching part contains at least one label already.\n    //\n    // in this case, we will need to have a `,` character at the end,\n    // to be able to suggest adding the next label.\n    // the area between the end-of-the-child-node and the cursor-pos\n    // must contain a `,` in this case.\n    const textToCheck = text.slice(child.to, pos);\n\n    if (!textToCheck.includes(',')) {\n      return null;\n    }\n  }\n\n  // next false positive:\n  // `{\"utf8.metric\"^}`\n  child = walk(node, [['firstChild', QuotedLabelName]]);\n  if (child !== null) {\n    // means the label-matching part contains a utf8 metric.\n    //\n    // in this case, we will need to have a `,` character at the end,\n    // to be able to suggest adding the next label.\n    // the area between the end-of-the-child-node and the cursor-pos\n    // must contain a `,` in this case.\n    const textToCheck = text.slice(child.to, pos);\n\n    if (!textToCheck.includes(',')) {\n      return null;\n    }\n  }\n\n  const otherLabels = getLabels(node, text);\n  const metricName = getMetricName(node, text);\n\n  return {\n    type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',\n    otherLabels,\n    betweenQuotes: false,\n    ...(metricName ? { metricName } : {}),\n  };\n}\n\nfunction resolveUtf8LabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {\n  const otherLabels = getLabels(node, text);\n  const metricName = node.parent?.parent ? getMetricName(node.parent.parent, text) : null;\n\n  return {\n    type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',\n    otherLabels,\n    betweenQuotes: true,\n    ...(metricName ? { metricName } : {}),\n  };\n}\n\nfunction getMetricName(node: SyntaxNode, text: string): string | null {\n  // Legacy Metric metric_name{label=\"value\"}\n  const legacyMetricNameNode = walk(node, [\n    ['parent', VectorSelector],\n    ['firstChild', Identifier],\n  ]);\n\n  if (legacyMetricNameNode) {\n    return getNodeText(legacyMetricNameNode, text);\n  }\n\n  // check for a utf-8 metric\n  // utf-8 metric {\"metric.name\", label=\"value\"}\n  const utf8MetricNameNode = walk(node, [\n    ['parent', VectorSelector],\n    ['firstChild', LabelMatchers],\n    ['firstChild', QuotedLabelName],\n    ['firstChild', StringLiteral],\n  ]);\n\n  if (utf8MetricNameNode) {\n    return getNodeText(utf8MetricNameNode, text, true);\n  }\n\n  // no metric name\n  return null;\n}\n\n// we find the first error-node in the tree that is at the cursor-position.\n// NOTE: this might be too slow, might need to optimize it\n// (ideas: we do not need to go into every subtree, based on from/to)\n// also, only go to places that are in the sub-tree of the node found\n// by default by lezer. problem is, `next()` will go upward too,\n// and we do not want to go higher than our node\nfunction getErrorNode(tree: Tree, pos: number): SyntaxNode | null {\n  const cur = tree.cursorAt(pos);\n  while (true) {\n    if (cur.from === pos && cur.to === pos) {\n      const { node } = cur;\n      if (node.type.isError) {\n        return node;\n      }\n    }\n\n    if (!cur.next()) {\n      break;\n    }\n  }\n  return null;\n}\n\nexport function getSituation(text: string, pos: number): Situation | null {\n  // there is a special-case when we are at the start of writing text,\n  // so we handle that case first\n\n  if (text === '') {\n    return {\n      type: 'EMPTY',\n    };\n  }\n\n  /**\n   PromQL\n   Expr\n   VectorSelector\n   LabelMatchers\n   */\n  const tree = parser.parse(text);\n\n  // if the tree contains error, it is very probable that\n  // our node is one of those error-nodes.\n  // also, if there are errors, the node lezer finds us,\n  // might not be the best node.\n  // so first we check if there is an error-node at the cursor-position\n  const maybeErrorNode = getErrorNode(tree, pos);\n\n  const cur = maybeErrorNode != null ? maybeErrorNode.cursor() : tree.cursorAt(pos);\n  const currentNode = cur.node;\n\n  const ids = [cur.type.id];\n  while (cur.parent()) {\n    ids.push(cur.type.id);\n  }\n\n  for (let resolver of RESOLVERS) {\n    // i do not use a foreach because i want to stop as soon\n    // as i find something\n    if (isPathMatch(resolver.path, ids)) {\n      return resolver.fun(currentNode, text, pos);\n    }\n  }\n\n  return null;\n}\n\nfunction notEmpty<TValue>(value: TValue | null | undefined): value is TValue {\n  return value !== null && value !== undefined;\n}\n"],"names":[],"mappings":"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"}