/**
 * Extract a parenthesized expression from a string, handling nested parens
 * e.g., "func(a, fn(b, c))" -> { expression: "func(a, fn(b, c))", endPos: 17 }
 *
 * Returns `null` for the legacy callers; use `extractParenthesizedExpressionDetailed`
 * when you need to know WHY extraction failed (helpful for directive error
 * messages pointing at the source location of a malformed `@if(`).
 */
export declare function extractParenthesizedExpression(source: string, startPos: number): {
  expression: string
  endPos: number
} | null;
export declare function extractParenthesizedExpressionDetailed(source: string, startPos: number): ExtractParenResult;
/**
 * Find the matching end tag for a directive, handling nested instances
 *
 * @param source - The source string to search in
 * @param startName - The opening directive name (e.g., "if", "foreach")
 * @param endName - The closing directive name (e.g., "endif", "endforeach")
 * @param startPos - Position to start searching from (after the opening directive)
 * @returns The position of the matching end tag, or -1 if not found
 */
export declare function findMatchingEndTag(source: string, startName: string, endName: string, startPos: number): number;
/**
 * Parse a complete conditional block (@if, @elseif, @else, @endif)
 *
 * @param source - The source string
 * @param startPos - Position where @if starts
 * @returns Parsed conditional with all branches, or null if malformed
 */
export declare function parseConditionalBlock(source: string, startPos: number): ParsedConditional | null;
/**
 * Find all @if blocks in source (non-nested, outermost only)
 */
export declare function findIfBlocks(source: string): ParsedConditional[];
/**
 * Find a directive with its content
 *
 * @param source - Source string
 * @param directiveName - Name without @ (e.g., "foreach")
 * @param endDirectiveName - End name without @ (e.g., "endforeach")
 * @returns All matches found
 */
export declare function findDirectiveBlocks(source: string, directiveName: string, endDirectiveName: string): DirectiveMatch[];
export declare function parseSwitchBlock(source: string, startPos: number): ParsedSwitch | null;
// =============================================================================
// Types
// =============================================================================
export declare interface DirectiveMatch {
  fullMatch: string
  name: string
  params: string
  content: string
  start: number
  end: number
}
export declare interface ConditionalBranch {
  type: 'if' | 'elseif' | 'else'
  condition?: string
  content: string
  start: number
  end: number
}
export declare interface ParsedConditional {
  fullMatch: string
  branches: ConditionalBranch[]
  start: number
  end: number
}
/**
 * Parse @switch block with proper handling of nested switches
 */
export declare interface SwitchCase {
  type: 'case' | 'default'
  value?: string
  content: string
}
export declare interface ParsedSwitch {
  fullMatch: string
  expression: string
  cases: SwitchCase[]
  start: number
  end: number
}
/**
 * Structured variant of `extractParenthesizedExpression` — returns either a
 * successful parse or a `{ ok: false, reason, pos }` record explaining the
 * failure. Use this when emitting user-facing errors ("missing opening
 * paren", "unclosed paren at column N", etc.).
 */
export type ExtractParenResult = | { ok: true, expression: string, endPos: number }
  | { ok: false, reason: 'missing-open-paren' | 'unclosed-paren', pos: number }
