{"version":3,"file":"msgfmt-parser-types.mjs","names":[],"sources":["../src/msgfmt-parser-types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any */\n\n// The parser algorithm is written to vastly match what is implemented in ./msgfmt-parser.ts, but with a few differences.\n\nimport type { Message } from \"./index.js\";\n\ndeclare const componentPlaceholderSymbol: unique symbol;\nexport type ComponentPlaceholder = typeof componentPlaceholderSymbol;\n\nexport type ParseResult<\n  Accum,\n  Rem extends string,\n  Error extends string | undefined\n> = {\n  AccumRev: (x: Accum) => void;\n  Rem: Rem;\n  Error: Error;\n};\n\nexport type ParseError<Error extends string> = { error: Error };\n\nexport type InferredMessageType<S extends string> = ParseMessageEOF<\n  S,\n  {}\n> extends ParseResult<infer Accum, any, infer Error>\n  ? Error extends string\n    ? ParseError<Error>\n    : Accum[] extends never[]\n    ? unknown\n    : Message<Accum>\n  : unknown;\n\ntype ValidArgType =\n  | \"number\"\n  | \"date\"\n  | \"time\"\n  | \"spellout\"\n  | \"ordinal\"\n  | \"duration\";\n\ntype ValidArgStyle = {\n  number: \"integer\" | \"currency\" | \"percent\";\n  date: \"short\" | \"medium\" | \"long\" | \"full\";\n  time: \"short\" | \"medium\" | \"long\" | \"full\";\n  spellout: never;\n  ordinal: never;\n  duration: never;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\ntype ParseMessageEOF<S extends string, Accum> = ParseMessage<\n  S,\n  Accum\n> extends ParseResult<infer Accum, infer Rem, infer Error>\n  ? Error extends string\n    ? ParseResult<Accum, Rem, Error>\n    : Rem extends `${infer RemH}${infer _Rem}`\n    ? ParseResult<Accum, Rem, `Found an unmatching ${RemH}`>\n    : Rem extends \"\"\n    ? ParseResult<Accum, Rem, Error>\n    : ParseResult<never, Rem, Error>\n  : never;\n\ntype ParseMessage<S extends string, Accum> = S extends\n  | `}${string}`\n  | `</${string}`\n  | \"\"\n  ? ParseResult<Accum, S, undefined>\n  : S extends `{${infer ST}`\n  ? ParseArgument<ST, Accum>\n  : S extends `''${infer STT}`\n  ? ParseMessage<STT, Accum>\n  : S extends `'${infer ST}`\n  ? ST extends `${\"{\" | \"}\" | \"#\" | \"|\" | \"<\"}${string}`\n    ? ParseQuoted<ST, Accum>\n    : ParseMessage<ST, Accum>\n  : S extends `<${infer ST}`\n  ? ParseElement<ST, Accum>\n  : S extends `${string}${infer ST}`\n  ? ParseMessage<ST, Accum>\n  : ParseResult<never, S, undefined>;\n\n// After \"'\"\ntype ParseQuoted<S extends string, Accum> = S extends `''${infer ST}`\n  ? ParseQuoted<ST, Accum>\n  : S extends `'${infer ST}`\n  ? ParseMessage<ST, Accum>\n  : S extends \"\"\n  ? ParseResult<Accum, S, \"Unclosed quoted string\">\n  : S extends `${string}${infer ST}`\n  ? ParseQuoted<ST, Accum>\n  : ParseResult<never, S, undefined>;\n\ntype ParseArgument<S extends string, Accum> = NextToken<S> extends Token<\n  \"identifier\" | \"number\",\n  infer Name,\n  infer ST\n>\n  ? CheckName<Name> extends ParseError<infer Error>\n    ? ParseResult<Accum, S, Error>\n    : NextToken<ST> extends Token<\"}\", any, infer STT>\n    ? ParseMessage<STT, Accum & Record<CheckName<Name>, string>>\n    : NextToken<ST> extends Token<\",\", any, infer STT>\n    ? NextToken<STT> extends Token<\"identifier\", \"choice\", any>\n      ? ParseResult<Accum, S, \"choice is not supported\">\n      : NextToken<STT> extends Token<\"identifier\", \"plural\", infer STTT>\n      ? ParsePluralArgument<STTT, CheckName<Name>, Accum>\n      : NextToken<STT> extends Token<\n          \"identifier\",\n          \"select\" | \"selectordinal\",\n          any\n        >\n      ? ParseResult<Accum, S, \"Unimplemented: selectArg\">\n      : NextToken<STT> extends Token<\"identifier\", ValidArgType, infer STTT>\n      ? NextToken<STTT> extends Token<\"}\", any, infer STTTT>\n        ? ParseMessage<\n            STTTT,\n            Accum & Record<CheckName<Name>, ArgTypeMap[NextToken<STT>[1]]>\n          >\n        : NextToken<STTT> extends Token<\",\", any, infer STTTT>\n        ? NextToken<STTTT> extends Token<\n            \"identifier\",\n            ValidArgStyle[NextToken<STT>[1]],\n            infer STTTTT\n          >\n          ? NextToken<STTTTT> extends Token<\"}\", any, infer STTTTTT>\n            ? ParseMessage<\n                STTTTTT,\n                Accum & Record<CheckName<Name>, ArgTypeMap[NextToken<STT>[1]]>\n              >\n            : ParseResult<\n                Accum,\n                S,\n                `Unexpected token ${NextToken<STTTTT>[0]} (expected })`\n              >\n          : NextToken<STTTT> extends Token<\"identifier\", any, any>\n          ? ParseResult<\n              Accum,\n              S,\n              `Invalid argStyle for ${NextToken<STT>[1]}: ${NextToken<STTTT>[1]}`\n            >\n          : NextToken<STTTT> extends Token<\"::\", any, infer STTTTT>\n          ? NextToken<STTTTT> extends Token<\"identifier\", any, infer STTTTTT>\n            ? // TODO: parse skeletons\n              NextToken<STTTTTT> extends Token<\"}\", any, infer STTTTTTT>\n              ? ParseMessage<\n                  STTTTTTT,\n                  Accum & Record<CheckName<Name>, ArgTypeMap[NextToken<STT>[1]]>\n                >\n              : ParseResult<\n                  Accum,\n                  S,\n                  `Unexpected token ${NextToken<STTTTT>[0]} (expected })`\n                >\n            : ParseResult<\n                Accum,\n                S,\n                `Unexpected token ${NextToken<STTTTT>[0]} (expected identifier)`\n              >\n          : ParseResult<\n              Accum,\n              S,\n              `Unexpected token ${NextToken<STTTT>[0]} (expected identifier, ::)`\n            >\n        : ParseResult<\n            Accum,\n            S,\n            `Unexpected token ${NextToken<STTT>[0]} (expected }, ,)`\n          >\n      : NextToken<STT> extends Token<\"identifier\", any, any>\n      ? ParseResult<Accum, S, `Invalid argType: ${NextToken<STT>[1]}`>\n      : ParseResult<\n          Accum,\n          S,\n          `Unexpected token ${NextToken<STT>[0]} (expected identifier)`\n        >\n    : ParseResult<\n        Accum,\n        S,\n        `Unexpected token ${NextToken<ST>[0]} (expected }, ,)`\n      >\n  : ParseResult<\n      Accum,\n      S,\n      `Unexpected token ${NextToken<S>[0]} (expected number, identifier)`\n    >;\n\ntype ParsePluralArgument<\n  S extends string,\n  Name extends string | number,\n  Accum\n> = NextToken<S> extends Token<\",\", any, infer ST>\n  ? NextToken<ST> extends Token<\"offset:\", any, infer STT>\n    ? NextToken<STT> extends Token<\"number\", infer Offset, infer STTT>\n      ? CheckNumber<Offset> extends ParseError<infer Error>\n        ? ParseResult<Accum, S, Error>\n        : ParsePluralArgument2<STTT, Name, undefined, Accum>\n      : ParseResult<\n          Accum,\n          S,\n          `Unexpected token ${NextToken<STT>[0]} (expected number)`\n        >\n    : NextToken<ST> extends Token<\"identifier\" | \"=\" | \"}\", any, any>\n    ? ParsePluralArgument2<ST, Name, undefined, Accum>\n    : ParseResult<\n        Accum,\n        S,\n        `Unexpected token ${NextToken<ST>[0]} (expected offset:, identifier, =, })`\n      >\n  : ParseResult<Accum, S, `Unexpected token ${NextToken<S>[0]} (expected ,)`>;\n\ntype ParsePluralArgument2<\n  S extends string,\n  Name extends string | number,\n  LastSelector extends string | undefined,\n  Accum\n> = NextToken<S> extends Token<\"=\", any, infer ST>\n  ? NextToken<ST> extends Token<\"number\", infer Selector, infer STT>\n    ? ST extends HasWhitespace\n      ? ParseResult<Accum, S, \"No space allowed here\">\n      : CheckNumber<Selector> extends ParseError<infer Error>\n      ? ParseResult<Accum, S, Error>\n      : ParsePluralArgument3<STT, Name, Selector, Accum>\n    : ParseResult<\n        Accum,\n        S,\n        `Unexpected token ${NextToken<ST>[0]} (expected number)`\n      >\n  : NextToken<S> extends Token<\"identifier\", infer Selector, infer ST>\n  ? ParsePluralArgument3<ST, Name, Selector, Accum>\n  : NextToken<S> extends Token<\"}\", any, infer ST>\n  ? LastSelector extends \"other\"\n    ? ParseMessage<ST, Accum & Record<Name, number>>\n    : LastSelector extends string\n    ? ParseResult<Accum, S, \"Last selector should be other\">\n    : ParseResult<Accum, S, \"No branch found\">\n  : ParseResult<\n      Accum,\n      S,\n      `Unexpected token ${NextToken<S>[0]} (expected identifier, =, })`\n    >;\n\ntype ParsePluralArgument3<\n  S extends string,\n  Name extends string | number,\n  Selector extends string | undefined,\n  Accum\n> = NextToken<S> extends Token<\"{\", any, infer STT>\n  ? ParseMessage<STT, Accum> extends ParseResult<\n      infer Accum,\n      infer Rem,\n      infer Error\n    >\n    ? Error extends string\n      ? ParseResult<Accum, Rem, Error>\n      : NextToken<Rem> extends Token<\"}\", any, infer RemT>\n      ? ParsePluralArgument2<RemT, Name, Selector, Accum>\n      : ParseResult<\n          Accum,\n          Rem,\n          `Unexpected token ${NextToken<Rem>[0]} (expected })`\n        >\n    : never\n  : ParseResult<Accum, S, `Unexpected token ${NextToken<S>[0]} (expected {)`>;\n\ntype ParseElement<S extends string, Accum> = NextToken<S> extends Token<\n  \"identifier\" | \"number\",\n  infer Name,\n  infer ST\n>\n  ? S extends HasWhitespace\n    ? ParseResult<Accum, S, \"No space allowed here\">\n    : CheckName<Name> extends ParseError<infer Error>\n    ? ParseResult<Accum, S, Error>\n    : NextToken<ST> extends Token<\"/\", any, infer STT>\n    ? NextToken<STT> extends Token<\">\", any, infer STTT>\n      ? STT extends HasWhitespace\n        ? ParseResult<Accum, S, \"No space allowed here\">\n        : ParseMessage<\n            STTT,\n            Accum & Record<CheckName<Name>, ComponentPlaceholder>\n          >\n      : ParseResult<\n          Accum,\n          S,\n          `Unexpected token ${NextToken<STT>[0]} (expected >)`\n        >\n    : NextToken<ST> extends Token<\">\", any, infer STT>\n    ? ParseMessage<STT, Accum> extends ParseResult<\n        infer Accum,\n        infer Rem,\n        infer Error\n      >\n      ? Error extends string\n        ? ParseResult<Accum, Rem, Error>\n        : NextToken<Rem> extends Token<\"<\", any, infer RemT>\n        ? NextToken<RemT> extends Token<\"/\", any, infer RemTT>\n          ? RemT extends HasWhitespace\n            ? ParseResult<Accum, S, \"No space allowed here\">\n            : NextToken<RemTT> extends Token<\n                \"identifier\" | \"number\",\n                infer ClosingName,\n                infer RemTTT\n              >\n            ? RemTT extends HasWhitespace\n              ? ParseResult<Accum, S, \"No space allowed here\">\n              : NextToken<RemTTT> extends Token<\">\", any, infer RemTTTT>\n              ? NameEqual<Name, ClosingName> extends true\n                ? ParseMessage<\n                    RemTTTT,\n                    Accum & Record<CheckName<Name>, ComponentPlaceholder>\n                  >\n                : ParseResult<\n                    Accum,\n                    Rem,\n                    `Tag ${Name} closed with a different name: ${ClosingName}`\n                  >\n              : ParseResult<\n                  Accum,\n                  Rem,\n                  `Unexpected token ${NextToken<RemTTT>[0]} (expected >)`\n                >\n            : ParseResult<\n                Accum,\n                Rem,\n                `Unexpected token ${NextToken<RemTT>[0]} (expected number, identifier)`\n              >\n          : ParseResult<\n              Accum,\n              Rem,\n              `Unexpected token ${NextToken<RemT>[0]} (expected /)`\n            >\n        : ParseResult<\n            Accum,\n            Rem,\n            `Unexpected token ${NextToken<Rem>[0]} (expected <)`\n          >\n      : never\n    : ParseResult<\n        Accum,\n        S,\n        `Unexpected token ${NextToken<ST>[0]} (expected /, >)`\n      >\n  : ParseResult<\n      Accum,\n      S,\n      `Unexpected token ${NextToken<S>[0]} (expected number, identifier)`\n    >;\n\ntype CheckName<Name extends string> = Name extends \"0\"\n  ? 0\n  : Name extends `0${string}`\n  ? ParseError<`Invalid number: ${Name}`>\n  : Name extends `${Digit}${string}`\n  ? CheckNumberImpl<Name>\n  : Name;\n\ntype CheckNumber<Name extends string> = Name extends \"0\"\n  ? 0\n  : Name extends `0${string}`\n  ? ParseError<`Invalid number: ${Name}`>\n  : Name extends `${Digit}${string}`\n  ? CheckNumberImpl<Name>\n  : ParseError<`Invalid number: ${Name}`>;\n\ntype CheckNumberImpl<\n  Name extends string,\n  N extends string = Name\n> = N extends `${infer NH}${infer NT}`\n  ? NH extends Digit\n    ? CheckNumberImpl<Name, NT>\n    : ParseError<`Invalid number: ${Name}`>\n  : N extends \"\"\n  ? ParseNumber[Name]\n  : never;\n\ntype Token<Kind extends string, Value extends string, S extends string> = [\n  Kind,\n  Value,\n  S\n];\n\ntype NextToken<S extends string> =\n  SkipWhitespace<S> extends `offset:${infer ST}`\n    ? Token<\"offset:\", \"offset:\", ST>\n    : SkipWhitespace<S> extends `${Alpha}${string}`\n    ? NextWord<SkipWhitespace<S>, \"\", \"identifier\">\n    : SkipWhitespace<S> extends `${Digit}${string}`\n    ? NextWord<SkipWhitespace<S>, \"\", \"number\">\n    : SkipWhitespace<S> extends `::${infer ST}`\n    ? Token<\"::\", \"::\", ST>\n    : SkipWhitespace<S> extends `${infer SH}${infer ST}`\n    ? Token<SH, SH, ST>\n    : SkipWhitespace<S> extends \"\"\n    ? Token<\"EOF\", \"\", \"\">\n    : never;\n\ntype NextWord<\n  S extends string,\n  Name extends string,\n  Kind extends string\n> = S extends `${infer SH}${infer ST}`\n  ? SH extends Alpha | Digit\n    ? NextWord<ST, `${Name}${SH}`, Kind>\n    : Token<Kind, Name, S>\n  : S extends \"\"\n  ? Token<Kind, Name, S>\n  : never;\n\ntype HasWhitespace = `${Whitespace}${string}`;\n\ntype SkipWhitespace<S extends string> = S extends `${Whitespace}${infer ST}`\n  ? SkipWhitespace<ST>\n  : S;\n\ntype NameEqual<N1 extends string, N2 extends string> = N1 extends N2\n  ? N2 extends N1\n    ? true\n    : false\n  : false;\n\ntype ArgTypeMap = {\n  number: number;\n  date: Date;\n  time: Date;\n  spellout: number;\n  ordinal: number;\n  duration: number;\n};\n\ntype Whitespace = \" \" | \"\\n\" | \"\\r\" | \"\\t\";\ntype Digit = \"0\" | \"1\" | \"2\" | \"3\" | \"4\" | \"5\" | \"6\" | \"7\" | \"8\" | \"9\";\ntype Alpha =\n  | \"a\"\n  | \"b\"\n  | \"c\"\n  | \"d\"\n  | \"e\"\n  | \"f\"\n  | \"g\"\n  | \"h\"\n  | \"i\"\n  | \"j\"\n  | \"k\"\n  | \"l\"\n  | \"m\"\n  | \"n\"\n  | \"o\"\n  | \"p\"\n  | \"q\"\n  | \"r\"\n  | \"s\"\n  | \"t\"\n  | \"u\"\n  | \"v\"\n  | \"w\"\n  | \"x\"\n  | \"y\"\n  | \"z\"\n  | \"A\"\n  | \"B\"\n  | \"C\"\n  | \"D\"\n  | \"E\"\n  | \"F\"\n  | \"G\"\n  | \"H\"\n  | \"I\"\n  | \"J\"\n  | \"K\"\n  | \"L\"\n  | \"M\"\n  | \"N\"\n  | \"O\"\n  | \"P\"\n  | \"Q\"\n  | \"R\"\n  | \"S\"\n  | \"T\"\n  | \"U\"\n  | \"V\"\n  | \"W\"\n  | \"X\"\n  | \"Y\"\n  | \"Z\"\n  | \"_\";\n\ntype ParseNumber = {\n  \"0\": 0;\n  \"1\": 1;\n  \"2\": 2;\n  \"3\": 3;\n  \"4\": 4;\n  \"5\": 5;\n  \"6\": 6;\n  \"7\": 7;\n  \"8\": 8;\n  \"9\": 9;\n  \"10\": 10;\n  \"11\": 11;\n  \"12\": 12;\n  \"13\": 13;\n  \"14\": 14;\n  \"15\": 15;\n  \"16\": 16;\n  [key: string]: number;\n};\n"],"mappings":""}