generateForLanguage method

Future<String> generateForLanguage(
  1. String sourcePath,
  2. String targetLang, {
  3. bool overwrite = true,
})

Generates a translated localization file for the specified targetLang based on the sourcePath file.

Supports multiple formats (ARB, JSON, YAML, CSV) and uses context-aware translation with AI providers for high-quality results.

Example:

final translator = LocalizationTranslator(config);
await translator.generateForLanguage('lib/l10n/app_en.arb', 'fr');
// Generates lib/l10n/app_fr.arb

sourcePath: The path to the source localization file. targetLang: The ISO-639 language code for the target translation. overwrite: Whether to overwrite existing files (default: true).

Returns a Future<String> with the path to the generated file.

Implementation

Future<String> generateForLanguage(
  String sourcePath,
  String targetLang, {
  bool overwrite = true,
}) async {
  _logger.info('Starting translation: $sourcePath -> $targetLang');

  try {
    // Read and validate source ARB file
    final sourceContent = await ArbHelper.readArbFile(sourcePath);
    _logger.debug('Source file loaded with ${sourceContent.length} entries');

    // Check if target file exists and handle overwrite
    final targetPath = _generateTargetPath(sourcePath, targetLang);
    if (!overwrite && await File(targetPath).exists()) {
      _logger.warning(
        'Target file exists and overwrite is disabled: $targetPath',
      );
      throw ArbFileWriteException(
        targetPath,
        'File exists and overwrite is disabled',
      );
    }

    // Extract translations (non-metadata entries)
    final translations = ArbHelper.getTranslations(sourceContent);
    final metadata = ArbHelper.getMetadata(sourceContent);

    if (translations.isEmpty) {
      _logger.warning('No translatable content found in source file');
      throw ArbValidationException(
        sourcePath,
        ['No translatable content found'],
      );
    }

    _logger.info('Found ${translations.length} entries to translate');

    // Perform context-aware translations with batch processing
    final translatedResults = <String, String>{};

    for (final entry in translations.entries) {
      final text = entry.value.toString();
      if (text.trim().isNotEmpty) {
        // Extract context for this translation
        final context = ArbHelper.extractTranslationContext(sourceContent, entry.key);
        final description = context['description'] as String?;
        final surrounding = context['surrounding'] as Map<String, String>?;

        try {
          final translatedText = await _translationService.translateText(
            text,
            targetLang,
            sourceLang: sourceContent['@@locale'] as String?,
            description: description,
            surroundingContext: surrounding,
            keyName: entry.key,
          );
          translatedResults[entry.key] = translatedText;
        } catch (e) {
          _logger.warning('Failed to translate ${entry.key}: $e');
          // Keep original text on failure
          translatedResults[entry.key] = text;
        }
      }
    }

    // Build target content
    final targetContent = <String, dynamic>{};

    // Add metadata with updated locale
    for (final entry in metadata.entries) {
      if (entry.key == '@@locale') {
        targetContent[entry.key] = targetLang;
      } else if (_config.preserveMetadata) {
        targetContent[entry.key] = entry.value;
      }
    }

    // Add translations
    for (final entry in translations.entries) {
      final translatedText = translatedResults[entry.key];
      targetContent[entry.key] = translatedText ?? entry.value;

      if (translatedText != null) {
        _logger.debug('Translated ${entry.key}: "$translatedText"');
      }
    }

    // Write target ARB file
    await ArbHelper.writeArbFile(
      targetPath,
      targetContent,
      prettyPrint: _config.prettyPrintJson,
      createBackup: _config.backupOriginal,
    );

    // Validate output if configured
    if (_config.validateOutput) {
      await _validateGeneratedFile(targetPath);
    }

    _logger.success('Generated $targetPath successfully!');
    return targetPath;
  } catch (e) {
    _logger.error('Failed to generate ARB file for $targetLang', e);
    rethrow;
  }
}