import { parseJSON, getStaticJSONValue, traverseNodes } from 'jsonc-eslint-parser';
import { isBoolean, format, escapeHtml, friendlyJSONstringify, isString, isNumber } from '@intlify/shared';
import { SourceMapGenerator, SourceMapConsumer } from 'source-map-js';
import { LOCATION_STUB, detectHtmlTag, baseCompile } from '@intlify/message-compiler';
import MagicString from 'magic-string';
import { parseYAML, getStaticYAMLValue, traverseNodes as traverseNodes$1 } from 'yaml-eslint-parser';
import { parse } from 'acorn';
import { generate as generate$3 } from 'escodegen';
import { walk } from 'estree-walker';
import module from 'node:module';

function createCodeGenerator(options = {
  filename: "bundle.json",
  sourceMap: false,
  env: "development",
  forceStringify: false
}) {
  const { sourceMap, source, filename } = options;
  const _context = Object.assign(
    {
      code: "",
      column: 1,
      line: 1,
      offset: 0,
      map: void 0,
      indentLevel: 0
    },
    options
  );
  const context = () => _context;
  function push(code, node, name) {
    _context.code += code;
    if (_context.map && node) {
      if (node.loc && node.loc !== LOCATION_STUB) {
        addMapping(node.loc.start, name);
      }
      advancePositionWithSource(_context, code);
    }
  }
  function _newline(n) {
    push("\n" + `  `.repeat(n));
  }
  function indent(withNewLine = true) {
    const level = ++_context.indentLevel;
    withNewLine && _newline(level);
  }
  function deindent(withNewLine = true) {
    const level = --_context.indentLevel;
    withNewLine && _newline(level);
  }
  function newline() {
    _newline(_context.indentLevel);
  }
  function pushline(code, node, name) {
    push(code, node, name);
    newline();
  }
  function addMapping(loc, name) {
    _context.map.addMapping({
      name,
      source: _context.filename,
      original: {
        line: loc.line,
        column: loc.column - 1
      },
      generated: {
        line: _context.line,
        column: _context.column - 1
      }
    });
  }
  if (sourceMap && source) {
    _context.map = new SourceMapGenerator();
    _context.map.setSourceContent(filename, source);
  }
  return {
    context,
    push,
    indent,
    deindent,
    newline,
    pushline
  };
}
function advancePositionWithSource(pos, source, numberOfCharacters = source.length) {
  if (pos.offset == null) {
    return pos;
  }
  let linesCount = 0;
  let lastNewLinePos = -1;
  for (let i = 0; i < numberOfCharacters; i++) {
    if (source.charCodeAt(i) === 10) {
      linesCount++;
      lastNewLinePos = i;
    }
  }
  pos.offset += numberOfCharacters;
  pos.line += linesCount;
  pos.column = lastNewLinePos === -1 ? pos.column + numberOfCharacters : numberOfCharacters - lastNewLinePos;
  return pos;
}
const DETECT_MESSAGE = `Detected HTML in '{msg}' message.`;
const ON_ERROR_NOOP = () => {
};
function parsePath(path) {
  return path ? path.join(".") : "";
}
function generateMessageFunction(msg, options = {}, path) {
  const env = options.env != null ? options.env : "development";
  const strictMessage = isBoolean(options.strictMessage) ? options.strictMessage : true;
  const escapeHtml$1 = !!options.escapeHtml;
  const onError = options.onError || ON_ERROR_NOOP;
  const errors = [];
  let detecteHtmlInMsg = false;
  if (detectHtmlTag(msg)) {
    detecteHtmlInMsg = true;
    if (strictMessage) {
      const errMsg = format(DETECT_MESSAGE, { msg });
      onError(format(errMsg), {
        source: msg,
        path: parsePath(path)
      });
    }
  }
  const _msg = detecteHtmlInMsg && escapeHtml$1 ? escapeHtml(msg) : msg;
  const newOptions = Object.assign({ mode: "arrow" }, options);
  newOptions.onError = (err) => {
    if (onError) {
      const extra = {
        source: msg,
        path: parsePath(path),
        code: err.code,
        domain: err.domain,
        location: err.location
      };
      onError(err.message, extra);
      errors.push(err);
    }
  };
  const { code, ast, map } = baseCompile(_msg, newOptions);
  const occured = errors.length > 0;
  const genCode = !occured ? env === "development" ? `(()=>{const fn=${code};fn.source=${JSON.stringify(msg)};return fn;})()` : `${code}` : `\`${_msg}\``;
  return { code: genCode, ast, map, errors };
}
function mapLinesColumns(resMap, codeMaps, inSourceMap) {
  if (!resMap) {
    return null;
  }
  const resMapConsumer = new SourceMapConsumer(resMap);
  const inMapConsumer = inSourceMap ? new SourceMapConsumer(inSourceMap) : null;
  const mergedMapGenerator = new SourceMapGenerator();
  let inMapFirstItem = null;
  if (inMapConsumer) {
    inMapConsumer.eachMapping((m) => {
      if (inMapFirstItem) {
        return;
      }
      inMapFirstItem = m;
    });
  }
  resMapConsumer.eachMapping((res) => {
    if (res.originalLine == null) {
      return;
    }
    const map = codeMaps.get(res.name);
    if (!map) {
      return;
    }
    let inMapOrigin = null;
    if (inMapConsumer) {
      inMapOrigin = inMapConsumer.originalPositionFor({
        line: res.originalLine,
        column: res.originalColumn - 1
      });
      if (inMapOrigin.source == null) {
        inMapOrigin = null;
        return;
      }
    }
    const mapConsumer = new SourceMapConsumer(map);
    mapConsumer.eachMapping((m) => {
      mergedMapGenerator.addMapping({
        original: {
          line: inMapFirstItem ? inMapFirstItem.originalLine + res.originalLine - 2 : res.originalLine,
          column: inMapFirstItem ? inMapFirstItem.originalColumn + res.originalColumn : res.originalColumn
        },
        generated: {
          line: inMapFirstItem ? inMapFirstItem.generatedLine + res.originalLine - 2 : res.originalLine,
          // map column with message format compilation code map
          column: inMapFirstItem ? inMapFirstItem.generatedColumn + res.originalColumn + m.generatedColumn : res.originalColumn + m.generatedColumn
        },
        source: inMapOrigin ? inMapOrigin.source : res.source,
        name: m.name
        // message format compilation code
      });
    });
  });
  const generator = mergedMapGenerator;
  const targetConsumer = inMapConsumer || resMapConsumer;
  targetConsumer.sources.forEach((sourceFile) => {
    generator._sources.add(sourceFile);
    const sourceContent = targetConsumer.sourceContentFor(sourceFile);
    if (sourceContent != null) {
      mergedMapGenerator.setSourceContent(sourceFile, sourceContent);
    }
  });
  generator._sourceRoot = inSourceMap ? inSourceMap.sourceRoot : resMap.sourceRoot;
  generator._file = inSourceMap ? inSourceMap.file : resMap.file;
  return generator.toJSON();
}
function generateResourceAst(msg, options = {}, path) {
  const env = options.env != null ? options.env : "development";
  const strictMessage = isBoolean(options.strictMessage) ? options.strictMessage : true;
  const escapeHtml$1 = !!options.escapeHtml;
  const onError = options.onError || ON_ERROR_NOOP;
  const errors = [];
  let detecteHtmlInMsg = false;
  if (detectHtmlTag(msg)) {
    detecteHtmlInMsg = true;
    if (strictMessage) {
      const errMsg = format(DETECT_MESSAGE, { msg });
      onError(format(errMsg), {
        source: msg,
        path: parsePath(path)
      });
    }
  }
  const _msg = detecteHtmlInMsg && escapeHtml$1 ? escapeHtml(msg) : msg;
  const newOptions = Object.assign(
    {
      location: env === "development",
      minify: isBoolean(options.minify) ? options.minify : env === "production"
    },
    options
  );
  if (newOptions.jit != null) {
    newOptions.jit = true;
  }
  newOptions.onError = (err) => {
    if (onError) {
      const extra = {
        source: msg,
        path: parsePath(path),
        code: err.code,
        domain: err.domain,
        location: err.location
      };
      onError(err.message, extra);
      errors.push(err);
    }
  };
  const { ast, map } = baseCompile(_msg, newOptions);
  const occured = errors.length > 0;
  const code = !occured ? `${friendlyJSONstringify(ast)}` : `\`${_msg}\``;
  return { code, ast, map, errors };
}
function excludeLocales({
  messages,
  onlyLocales
}) {
  const _messages = { ...messages };
  Object.keys(_messages).forEach((locale) => {
    if (!onlyLocales.includes(locale)) {
      delete _messages[locale];
    }
  });
  return _messages;
}

function generateLegacyCode({
  isGlobal = false,
  vueVersion = "v2.6"
}, generator) {
  const componentNamespace = `Component${vueVersion === "v2.6" ? ".options" : ""}`;
  const variableName = !isGlobal ? "__i18n" : "__i18nGlobal";
  const exportSyntax = "export default";
  const code = `${exportSyntax} function (Component) {
  ${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []
  ${componentNamespace}.${variableName}.push(${friendlyJSONstringify(
    generator()
  )})
  delete ${componentNamespace}._Ctor
}`;
  return code;
}

function generate$2(targetSource, {
  type = "plain",
  legacy = false,
  vueVersion = "v2.6",
  bridge = false,
  onlyLocales = [],
  exportESM = false,
  filename = "vue-i18n-loader.json",
  inSourceMap = void 0,
  locale = "",
  isGlobal = false,
  sourceMap = false,
  env = "development",
  forceStringify = false,
  onError = void 0,
  strictMessage = true,
  escapeHtml = false,
  useClassComponent = false,
  jit = false
}, injector) {
  let value = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource;
  const options = {
    type,
    bridge,
    exportESM,
    source: value,
    sourceMap,
    locale,
    isGlobal,
    inSourceMap,
    env,
    filename,
    forceStringify,
    onError,
    strictMessage,
    escapeHtml,
    useClassComponent,
    jit
  };
  const generator = createCodeGenerator(options);
  let ast = parseJSON(value, { filePath: filename });
  if (!locale && type === "sfc" && onlyLocales?.length) {
    const messages = getStaticJSONValue(ast);
    value = JSON.stringify(
      excludeLocales({
        messages,
        onlyLocales
      })
    );
    ast = parseJSON(value, { filePath: filename });
  }
  if (legacy && type === "sfc") {
    const gen = () => friendlyJSONstringify(getStaticJSONValue(ast));
    const code2 = generateLegacyCode({ isGlobal, vueVersion }, gen);
    const s = new MagicString(code2);
    return {
      ast,
      code: s.toString(),
      map: s.generateMap({
        file: filename,
        source: value,
        includeContent: true
      })
    };
  }
  const codeMaps = _generate$2(generator, ast, options, injector);
  const { code, map } = generator.context();
  const newMap = map && !jit ? mapLinesColumns(map.toJSON(), codeMaps, inSourceMap) || null : null;
  return {
    ast,
    code,
    map: newMap != null ? newMap : void 0
  };
}
function _generate$2(generator, node, options = {}, injector) {
  const propsCountStack = [];
  const pathStack = [];
  const itemsCountStack = [];
  const { forceStringify } = generator.context();
  const codeMaps = /* @__PURE__ */ new Map();
  const {
    type,
    bridge,
    exportESM,
    sourceMap,
    isGlobal,
    locale,
    useClassComponent,
    jit
  } = options;
  const codegenFn = jit ? generateResourceAst : generateMessageFunction;
  const componentNamespace = "_Component";
  traverseNodes(node, {
    enterNode(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "plain") {
            generator.push(`const resource = `);
          } else if (type === "sfc") {
            const variableName = type === "sfc" ? !isGlobal ? "__i18n" : "__i18nGlobal" : "";
            const localeName = type === "sfc" ? locale != null ? locale : `""` : "";
            const exportSyntax = bridge ? exportESM ? `export default` : `module.exports =` : `export default`;
            generator.push(`${exportSyntax} function (Component) {`);
            generator.indent();
            const componentVariable = bridge ? `Component.options || Component` : useClassComponent ? `Component.__o || Component.__vccOpts || Component` : `Component`;
            generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
            generator.pushline(
              `${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
            );
            generator.push(`${componentNamespace}.${variableName}.push({`);
            generator.indent();
            generator.pushline(`"locale": ${JSON.stringify(localeName)},`);
            generator.push(`"resource": `);
          }
          break;
        case "JSONObjectExpression":
          generator.push(`{`);
          generator.indent();
          propsCountStack.push(node2.properties.length);
          if (parent.type === "JSONArrayExpression") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.elements.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          break;
        case "JSONProperty":
          if (node2.value.type === "JSONLiteral" && (node2.key.type === "JSONLiteral" || node2.key.type === "JSONIdentifier")) {
            const name = node2.key.type === "JSONLiteral" ? node2.key.value : node2.key.name;
            const value = node2.value.value;
            if (isString(value)) {
              generator.push(`${JSON.stringify(name)}: `);
              pathStack.push(name.toString());
              const { code, map } = codegenFn(value, options, pathStack);
              sourceMap && map != null && codeMaps.set(value, map);
              generator.push(`${code}`, node2.value, value);
            } else {
              if (forceStringify) {
                const strValue = JSON.stringify(value);
                generator.push(`${JSON.stringify(name)}: `);
                pathStack.push(name.toString());
                const { code, map } = codegenFn(strValue, options, pathStack);
                sourceMap && map != null && codeMaps.set(strValue, map);
                generator.push(`${code}`, node2.value, strValue);
              } else {
                generator.push(
                  `${JSON.stringify(name)}: ${JSON.stringify(value)}`
                );
                pathStack.push(name.toString());
              }
            }
          } else if ((node2.value.type === "JSONObjectExpression" || node2.value.type === "JSONArrayExpression") && (node2.key.type === "JSONLiteral" || node2.key.type === "JSONIdentifier")) {
            const name = node2.key.type === "JSONLiteral" ? node2.key.value : node2.key.name;
            generator.push(`${JSON.stringify(name)}: `);
            pathStack.push(name.toString());
          }
          const lastIndex = propsCountStack.length - 1;
          propsCountStack[lastIndex] = --propsCountStack[lastIndex];
          break;
        case "JSONArrayExpression":
          generator.push(`[`);
          generator.indent();
          if (parent.type === "JSONArrayExpression") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.elements.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          itemsCountStack.push(node2.elements.length);
          break;
        case "JSONLiteral":
          if (parent.type === "JSONArrayExpression") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.elements.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            if (node2.type === "JSONLiteral") {
              const value = node2.value;
              if (isString(value)) {
                const { code, map } = codegenFn(value, options, pathStack);
                sourceMap && map != null && codeMaps.set(value, map);
                generator.push(`${code}`, node2, value);
              } else {
                if (forceStringify) {
                  const strValue = JSON.stringify(value);
                  const { code, map } = codegenFn(strValue, options, pathStack);
                  sourceMap && map != null && codeMaps.set(strValue, map);
                  generator.push(`${code}`, node2, strValue);
                } else {
                  generator.push(`${JSON.stringify(value)}`);
                }
              }
            }
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          break;
      }
    },
    leaveNode(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "sfc") {
            generator.deindent();
            generator.push(`})`);
            if (bridge && injector) {
              generator.newline();
              generator.pushline(
                `${componentNamespace}.__i18nBridge = ${componentNamespace}.__i18nBridge || []`
              );
              generator.pushline(
                `${componentNamespace}.__i18nBridge.push('${injector()}')`
              );
              generator.pushline(`delete ${componentNamespace}._Ctor`);
            }
            generator.deindent();
            generator.pushline(`}`);
          } else if (type === "plain") {
            generator.push(`
`);
            generator.push("export default resource");
          }
          break;
        case "JSONObjectExpression":
          if (propsCountStack[propsCountStack.length - 1] === 0) {
            pathStack.pop();
            propsCountStack.pop();
          }
          generator.deindent();
          generator.push(`}`);
          if (parent.type === "JSONArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            }
          }
          break;
        case "JSONProperty":
          if (propsCountStack[propsCountStack.length - 1] !== 0) {
            pathStack.pop();
            generator.pushline(`,`);
          }
          break;
        case "JSONArrayExpression":
          if (itemsCountStack[itemsCountStack.length - 1] === 0) {
            pathStack.pop();
            itemsCountStack.pop();
          }
          generator.deindent();
          generator.push(`]`);
          if (parent.type === "JSONArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            }
          }
          break;
        case "JSONLiteral":
          if (parent.type === "JSONArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            } else {
              generator.pushline(`,`);
            }
          }
          break;
      }
    }
  });
  return codeMaps;
}

function generate$1(targetSource, {
  type = "plain",
  legacy = false,
  vueVersion = "v2.6",
  bridge = false,
  onlyLocales = [],
  exportESM = false,
  useClassComponent = false,
  filename = "vue-i18n-loader.yaml",
  inSourceMap = void 0,
  locale = "",
  isGlobal = false,
  sourceMap = false,
  env = "development",
  forceStringify = false,
  onError = void 0,
  strictMessage = true,
  escapeHtml = false,
  jit = false
}, injector) {
  let value = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource;
  const options = {
    type,
    bridge,
    exportESM,
    source: value,
    sourceMap,
    locale,
    isGlobal,
    inSourceMap,
    env,
    filename,
    forceStringify,
    onError,
    strictMessage,
    escapeHtml,
    useClassComponent,
    jit
  };
  const generator = createCodeGenerator(options);
  let ast = parseYAML(value, { filePath: filename });
  if (!locale && type === "sfc" && onlyLocales?.length) {
    const messages = getStaticYAMLValue(ast);
    value = JSON.stringify(
      excludeLocales({
        messages,
        onlyLocales
      })
    );
    ast = parseYAML(value, { filePath: filename });
  }
  if (legacy && type === "sfc") {
    const gen = () => friendlyJSONstringify(getStaticYAMLValue(ast));
    const code2 = generateLegacyCode({ isGlobal, vueVersion }, gen);
    const s = new MagicString(code2);
    return {
      ast,
      code: s.toString(),
      map: s.generateMap({
        file: filename,
        source: value,
        includeContent: true
      })
    };
  }
  const codeMaps = _generate$1(generator, ast, options, injector);
  const { code, map } = generator.context();
  const newMap = map ? mapLinesColumns(map.toJSON(), codeMaps, inSourceMap) || null : null;
  return {
    ast,
    code,
    map: newMap != null ? newMap : void 0
  };
}
function _generate$1(generator, node, options = {}, injector) {
  const propsCountStack = [];
  const pathStack = [];
  const itemsCountStack = [];
  const { forceStringify } = generator.context();
  const codeMaps = /* @__PURE__ */ new Map();
  const {
    type,
    bridge,
    exportESM,
    sourceMap,
    isGlobal,
    locale,
    useClassComponent,
    jit
  } = options;
  const codegenFn = jit ? generateResourceAst : generateMessageFunction;
  const componentNamespace = "_Component";
  traverseNodes$1(node, {
    enterNode(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "plain") {
            generator.push(`const resource = `);
          } else if (type === "sfc") {
            const variableName = type === "sfc" ? !isGlobal ? "__i18n" : "__i18nGlobal" : "";
            const localeName = type === "sfc" ? locale != null ? locale : `""` : "";
            const exportSyntax = bridge ? exportESM ? `export default` : `module.exports =` : `export default`;
            generator.push(`${exportSyntax} function (Component) {`);
            generator.indent();
            const componentVariable = bridge ? `Component.options || Component` : useClassComponent ? `Component.__o || Component.__vccOpts || Component` : `Component`;
            generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
            generator.pushline(
              `${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
            );
            generator.push(`${componentNamespace}.${variableName}.push({`);
            generator.indent();
            generator.pushline(`"locale": ${JSON.stringify(localeName)},`);
            generator.push(`"resource": `);
          }
          break;
        case "YAMLMapping":
          generator.push(`{`);
          generator.indent();
          propsCountStack.push(node2.pairs.length);
          if (parent.type === "YAMLSequence") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.entries.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          break;
        case "YAMLPair":
          if (node2.value && node2.value.type === "YAMLScalar" && node2.key && node2.key.type === "YAMLScalar") {
            const name = node2.key.value;
            const value = node2.value.value;
            if (isString(value)) {
              generator.push(`${JSON.stringify(name)}: `);
              name && pathStack.push(name.toString());
              const { code, map } = codegenFn(value, options, pathStack);
              sourceMap && map != null && codeMaps.set(value, map);
              generator.push(`${code}`, node2.value, value);
            } else {
              if (forceStringify) {
                const strValue = JSON.stringify(value);
                generator.push(`${JSON.stringify(name)}: `);
                name && pathStack.push(name.toString());
                const { code, map } = codegenFn(strValue, options, pathStack);
                sourceMap && map != null && codeMaps.set(strValue, map);
                generator.push(`${code}`, node2.value, strValue);
              } else {
                generator.push(
                  `${JSON.stringify(name)}: ${JSON.stringify(value)}`
                );
                name && pathStack.push(name.toString());
              }
            }
          } else if (node2.value && (node2.value.type === "YAMLMapping" || node2.value.type === "YAMLSequence") && node2.key && node2.key.type === "YAMLScalar") {
            const name = node2.key.value;
            generator.push(`${JSON.stringify(name)}: `);
            name && pathStack.push(name.toString());
          }
          const lastIndex = propsCountStack.length - 1;
          propsCountStack[lastIndex] = --propsCountStack[lastIndex];
          break;
        case "YAMLSequence":
          generator.push(`[`);
          generator.indent();
          if (parent.type === "YAMLSequence") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.entries.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          itemsCountStack.push(node2.entries.length);
          break;
        case "YAMLScalar":
          if (parent.type === "YAMLSequence") {
            const lastIndex2 = itemsCountStack.length - 1;
            const currentCount = parent.entries.length - itemsCountStack[lastIndex2];
            pathStack.push(currentCount.toString());
            if (node2.type === "YAMLScalar") {
              const value = node2.value;
              if (isString(value)) {
                const { code, map } = codegenFn(value, options, pathStack);
                sourceMap && map != null && codeMaps.set(value, map);
                generator.push(`${code}`, node2, value);
              } else {
                if (forceStringify) {
                  const strValue = JSON.stringify(value);
                  const { code, map } = codegenFn(strValue, options, pathStack);
                  sourceMap && map != null && codeMaps.set(strValue, map);
                  generator.push(`${code}`, node2, strValue);
                } else {
                  generator.push(`${JSON.stringify(value)}`);
                }
              }
            }
            itemsCountStack[lastIndex2] = --itemsCountStack[lastIndex2];
          }
          break;
      }
    },
    leaveNode(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "sfc") {
            generator.deindent();
            generator.push(`})`);
            if (bridge && injector) {
              generator.newline();
              generator.pushline(
                `${componentNamespace}.__i18nBridge = ${componentNamespace}.__i18nBridge || []`
              );
              generator.pushline(
                `${componentNamespace}.__i18nBridge.push('${injector()}')`
              );
              generator.pushline(`delete ${componentNamespace}._Ctor`);
            }
            generator.deindent();
            generator.push(`}`);
          } else if (type === "plain") {
            generator.push(`
`);
            generator.push("export default resource");
          }
          break;
        case "YAMLMapping":
          if (propsCountStack[propsCountStack.length - 1] === 0) {
            pathStack.pop();
            propsCountStack.pop();
          }
          generator.deindent();
          generator.push(`}`);
          if (parent.type === "YAMLSequence") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            }
          }
          break;
        case "YAMLPair":
          if (propsCountStack[propsCountStack.length - 1] !== 0) {
            pathStack.pop();
            generator.pushline(`,`);
          }
          break;
        case "YAMLSequence":
          if (itemsCountStack[itemsCountStack.length - 1] === 0) {
            pathStack.pop();
            itemsCountStack.pop();
          }
          generator.deindent();
          generator.push(`]`);
          if (parent.type === "YAMLSequence") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            }
          }
          break;
        case "YAMLScalar":
          if (parent.type === "YAMLSequence") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            } else {
              generator.pushline(`,`);
            }
          }
          break;
      }
    }
  });
  return codeMaps;
}

function generate(targetSource, {
  type = "plain",
  bridge = false,
  exportESM = false,
  filename = "vue-i18n-loader.js",
  inSourceMap = void 0,
  locale = "",
  isGlobal = false,
  sourceMap = false,
  env = "development",
  forceStringify = false,
  onError = void 0,
  strictMessage = true,
  escapeHtml = false,
  useClassComponent = false,
  allowDynamic = false,
  jit = false
}, injector) {
  const target = Buffer.isBuffer(targetSource) ? targetSource.toString() : targetSource;
  const value = target;
  const options = {
    type,
    bridge,
    exportESM,
    source: value,
    sourceMap,
    locale,
    isGlobal,
    inSourceMap,
    env,
    filename,
    forceStringify,
    onError,
    strictMessage,
    escapeHtml,
    useClassComponent,
    jit
  };
  const generator = createCodeGenerator(options);
  const ast = parse(value, {
    ecmaVersion: "latest",
    sourceType: "module",
    sourceFile: filename,
    allowImportExportEverywhere: true
  });
  const exportResult = scanAst(ast);
  if (!allowDynamic) {
    if (!exportResult || exportResult !== "object") {
      throw new Error(
        `You need to define an object as the locale message with 'export default'.`
      );
    }
  } else {
    if (!exportResult) {
      throw new Error(
        `You need to define 'export default' that will return the locale messages.`
      );
    }
    if (exportResult !== "object") {
      return {
        ast,
        code: value,
        map: inSourceMap
      };
    }
  }
  const codeMaps = _generate(generator, ast, options, injector);
  const { code, map } = generator.context();
  const newMap = map ? mapLinesColumns(map.toJSON(), codeMaps, inSourceMap) || null : null;
  return {
    ast,
    code,
    map: newMap != null ? newMap : void 0
  };
}
function scanAst(ast) {
  if (ast.type !== "Program") {
    throw new Error("Invalid AST: does not have Program node");
  }
  let ret = false;
  for (const node of ast.body) {
    if (node.type === "ExportDefaultDeclaration") {
      if (node.declaration.type === "ObjectExpression") {
        ret = "object";
        break;
      } else if (node.declaration.type === "FunctionDeclaration") {
        ret = "function";
        break;
      } else if (node.declaration.type === "ArrowFunctionExpression") {
        ret = "arrow-function";
        break;
      }
    }
  }
  return ret;
}
function _generate(generator, node, options = {}, injector) {
  const propsCountStack = [];
  const pathStack = [];
  const itemsCountStack = [];
  const skipStack = [];
  const { forceStringify } = generator.context();
  const codeMaps = /* @__PURE__ */ new Map();
  const {
    type,
    bridge,
    exportESM,
    sourceMap,
    isGlobal,
    locale,
    useClassComponent,
    jit
  } = options;
  const codegenFn = jit ? generateResourceAst : generateMessageFunction;
  const componentNamespace = "_Component";
  walk(node, {
    /**
     * NOTE:
     *  force cast to Node of `estree-walker@3.x`,
     *  because `estree-walker@3.x` is not dual packages,
     *  so it's support only esm only ...
     */
    // @ts-ignore
    enter(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "plain") {
            generator.push(`const resource = `);
          } else if (type === "sfc") {
            const variableName = type === "sfc" ? !isGlobal ? "__i18n" : "__i18nGlobal" : "";
            const localeName = type === "sfc" ? locale != null ? locale : `""` : "";
            const exportSyntax = bridge ? exportESM ? `export default` : `module.exports =` : `export default`;
            generator.push(`${exportSyntax} function (Component) {`);
            generator.indent();
            const componentVariable = bridge ? `Component.options || Component` : useClassComponent ? `Component.__o || Component.__vccOpts || Component` : `Component`;
            generator.pushline(`const ${componentNamespace} = ${componentVariable}`);
            generator.pushline(
              `${componentNamespace}.${variableName} = ${componentNamespace}.${variableName} || []`
            );
            generator.push(`${componentNamespace}.${variableName}.push({`);
            generator.indent();
            generator.pushline(`"locale": ${JSON.stringify(localeName)},`);
            generator.push(`"resource": `);
          }
          break;
        case "ObjectExpression":
          generator.push(`{`);
          generator.indent();
          propsCountStack.push(node2.properties.length);
          if (parent != null && parent.type === "ArrayExpression") {
            const lastIndex = itemsCountStack.length - 1;
            const currentCount = parent.elements.length - itemsCountStack[lastIndex];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
          }
          break;
        case "Property":
          if (parent != null && parent.type === "ObjectExpression") {
            if (node2 != null) {
              if (isJSONablePrimitiveLiteral(node2.value) && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
                const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
                if (node2.value.type === "Literal" && isString(node2.value.value) || node2.value.type === "TemplateLiteral") {
                  const value = getValue(node2.value);
                  generator.push(`${JSON.stringify(name)}: `);
                  pathStack.push(name);
                  const { code, map } = codegenFn(value, options, pathStack);
                  sourceMap && map != null && codeMaps.set(value, map);
                  generator.push(`${code}`, node2.value, value);
                  skipStack.push(false);
                } else {
                  const value = getValue(node2.value);
                  if (forceStringify) {
                    const strValue = JSON.stringify(value);
                    generator.push(`${JSON.stringify(name)}: `);
                    pathStack.push(name);
                    const { code, map } = codegenFn(
                      strValue,
                      options,
                      pathStack
                    );
                    sourceMap && map != null && codeMaps.set(strValue, map);
                    generator.push(`${code}`, node2.value, strValue);
                  } else {
                    generator.push(
                      `${JSON.stringify(name)}: ${JSON.stringify(value)}`
                    );
                    pathStack.push(name);
                  }
                  skipStack.push(false);
                }
              } else if ((node2.value.type === "FunctionExpression" || node2.value.type === "ArrowFunctionExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
                const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
                generator.push(`${JSON.stringify(name)}: `);
                pathStack.push(name);
                const code = generate$3(node2.value);
                generator.push(`${code}`, node2.value, code);
                skipStack.push(false);
              } else if ((node2.value.type === "ObjectExpression" || node2.value.type === "ArrayExpression") && (node2.key.type === "Literal" || node2.key.type === "Identifier")) {
                const name = node2.key.type === "Literal" ? String(node2.key.value) : node2.key.name;
                generator.push(`${JSON.stringify(name)}: `);
                pathStack.push(name);
              } else {
                skipStack.push(true);
              }
            }
            const lastIndex = propsCountStack.length - 1;
            propsCountStack[lastIndex] = --propsCountStack[lastIndex];
          }
          break;
        case "ArrayExpression":
          generator.push(`[`);
          generator.indent();
          if (parent != null && parent.type === "ArrayExpression") {
            const lastIndex = itemsCountStack.length - 1;
            const currentCount = parent.elements.length - itemsCountStack[lastIndex];
            pathStack.push(currentCount.toString());
            itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
          }
          itemsCountStack.push(node2.elements.length);
          break;
        default:
          if (node2 != null && parent != null) {
            if (parent.type === "ArrayExpression") {
              const lastIndex = itemsCountStack.length - 1;
              const currentCount = parent.elements.length - itemsCountStack[lastIndex];
              pathStack.push(currentCount.toString());
              if (isJSONablePrimitiveLiteral(node2)) {
                if (node2.type === "Literal" && isString(node2.value) || node2.type === "TemplateLiteral") {
                  const value = getValue(node2);
                  const { code, map } = codegenFn(value, options, pathStack);
                  sourceMap && map != null && codeMaps.set(value, map);
                  generator.push(`${code}`, node2, value);
                } else {
                  const value = getValue(node2);
                  if (forceStringify) {
                    const strValue = JSON.stringify(value);
                    const { code, map } = codegenFn(
                      strValue,
                      options,
                      pathStack
                    );
                    sourceMap && map != null && codeMaps.set(strValue, map);
                    generator.push(`${code}`, node2, strValue);
                  } else {
                    generator.push(`${JSON.stringify(value)}`);
                  }
                }
                skipStack.push(false);
              } else {
                skipStack.push(true);
              }
              itemsCountStack[lastIndex] = --itemsCountStack[lastIndex];
            }
          }
          break;
      }
    },
    /**
     * NOTE:
     *  force cast to Node of `estree-walker@3.x`,
     *  because `estree-walker@3.x` is not dual packages,
     *  so it's support only esm only ...
     */
    // @ts-ignore
    leave(node2, parent) {
      switch (node2.type) {
        case "Program":
          if (type === "sfc") {
            generator.deindent();
            generator.push(`})`);
            if (bridge && injector) {
              generator.newline();
              generator.pushline(
                `${componentNamespace}.__i18nBridge = ${componentNamespace}.__i18nBridge || []`
              );
              generator.pushline(
                `${componentNamespace}.__i18nBridge.push('${injector()}')`
              );
              generator.pushline(`delete ${componentNamespace}._Ctor`);
            }
            generator.deindent();
            generator.pushline(`}`);
          } else if (type === "plain") {
            generator.push(`
`);
            generator.push("export default resource");
          }
          break;
        case "ObjectExpression":
          if (propsCountStack[propsCountStack.length - 1] === 0) {
            pathStack.pop();
            propsCountStack.pop();
          }
          generator.deindent();
          generator.push(`}`);
          if (parent != null && parent.type === "ArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              generator.pushline(`,`);
            }
          }
          break;
        case "Property":
          if (parent != null && parent.type === "ObjectExpression") {
            if (propsCountStack[propsCountStack.length - 1] !== 0) {
              pathStack.pop();
              if (!skipStack.pop()) {
                generator.pushline(`,`);
              }
            }
          }
          break;
        case "ArrayExpression":
          if (itemsCountStack[itemsCountStack.length - 1] === 0) {
            pathStack.pop();
            itemsCountStack.pop();
          }
          generator.deindent();
          generator.push(`]`);
          if (parent != null && parent.type === "ArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              if (!skipStack.pop()) {
                generator.pushline(`,`);
              }
            }
          }
          break;
        case "Literal":
          if (parent != null && parent.type === "ArrayExpression") {
            if (itemsCountStack[itemsCountStack.length - 1] !== 0) {
              pathStack.pop();
              if (!skipStack.pop()) {
                generator.pushline(`,`);
              }
            } else {
              if (!skipStack.pop()) {
                generator.pushline(`,`);
              }
            }
          }
          break;
      }
    }
  });
  return codeMaps;
}
function isJSONablePrimitiveLiteral(node) {
  return node.type === "Literal" && (isString(node.value) || isNumber(node.value) || isBoolean(node.value) || node.value === null) || node.type === "TemplateLiteral";
}
function getValue(node) {
  return node.type === "Literal" ? node.value : node.type === "TemplateLiteral" ? node.quasis.map((quasi) => quasi.value.cooked).join("") : void 0;
}

const _require = module.createRequire(import.meta.url);
function checkInstallPackage(pkg, debug) {
  let installedVueI18n = false;
  try {
    debug(`vue-i18n load path: ${_require.resolve("vue-i18n")}`);
    installedVueI18n = true;
  } catch (e) {
    debug(`cannot find 'vue-i18n'`, e);
  }
  let installedPetiteVueI18n = false;
  try {
    debug(`petite-vue-i18n load path: ${_require.resolve("petite-vue-i18n")}`);
    installedPetiteVueI18n = true;
  } catch (e) {
    debug(`cannot find 'petite-vue-i18n'`, e);
  }
  if (installedVueI18n) {
    return "vue-i18n";
  }
  if (installedPetiteVueI18n) {
    return "petite-vue-i18n";
  }
  throw new Error(
    `${pkg} requires 'vue-i18n' or 'petite-vue-i18n' to be present in the dependency tree.`
  );
}
function checkVueI18nBridgeInstallPackage(debug) {
  let ret = false;
  try {
    debug(`vue-i18n-bridge load path: ${_require.resolve("vue-i18n-bridge")}`);
    ret = true;
  } catch (e) {
    debug(`cannot find 'vue-i18n-bridge'`, e);
  }
  return ret;
}
function getVueI18nVersion(debug) {
  const VueI18n = loadModule("vue-i18n", debug);
  if (VueI18n == null) {
    return "";
  }
  if (VueI18n.version && VueI18n.version.startsWith("8.")) {
    return "8";
  }
  if (VueI18n.VERSION && VueI18n.VERSION.startsWith("9.")) {
    return "9";
  }
  return "unknown";
}
function loadModule(moduleName, debug) {
  try {
    return _require(moduleName);
  } catch (e) {
    debug(`cannot load '${moduleName}'`, e);
    return null;
  }
}

export { checkInstallPackage, checkVueI18nBridgeInstallPackage, generate$2 as generateJSON, generate as generateJavaScript, generate$1 as generateYAML, getVueI18nVersion };
