AstBundle.fromZip constructor
Deserializes a bundle from ZIP archive bytes.
Reads the manifest to discover module URIs, then loads and decompresses each referenced module file.
Throws ArgumentD4rtException if the archive is invalid, the manifest is missing, or referenced module files are absent.
Implementation
factory AstBundle.fromZip(List<int> bytes) {
final Archive archive;
try {
archive = ZipDecoder().decodeBytes(bytes);
} catch (e) {
throw ArgumentD4rtException('Invalid ZIP archive: $e');
}
// Parse manifest
final manifestFile = archive.findFile(AstBundleFormat.manifestFileName);
if (manifestFile == null) {
throw ArgumentD4rtException(
'Invalid bundle archive: '
'missing "${AstBundleFormat.manifestFileName}"',
);
}
final manifestJson = jsonDecode(utf8.decode(manifestFile.content));
if (manifestJson is! Map<String, dynamic>) {
throw ArgumentD4rtException(
'Invalid bundle archive: manifest is not a valid JSON object',
);
}
final manifest = AstBundleManifest.fromJson(manifestJson);
// Load each module referenced by the manifest
final modules = <String, SCompilationUnit>{};
for (final entry in manifest.files.entries) {
final fileName = entry.key;
final uri = entry.value;
final file = archive.findFile(fileName);
if (file == null) {
throw ArgumentD4rtException(
'Invalid bundle archive: '
'module file "$fileName" referenced in manifest not found',
);
}
final moduleJson = _decodeModuleContent(file.content, uri, fileName);
modules[uri] = SCompilationUnit.fromJson(moduleJson);
}
// Load optional source files referenced by the manifest
Map<String, String>? sources;
if (manifest.sourceFiles != null && manifest.sourceFiles!.isNotEmpty) {
sources = <String, String>{};
for (final entry in manifest.sourceFiles!.entries) {
final srcFileName = entry.key;
final uri = entry.value;
final srcFile = archive.findFile(srcFileName);
if (srcFile != null) {
sources[uri] = utf8.decode(srcFile.content);
}
}
if (sources.isEmpty) sources = null;
}
return AstBundle(
entryPointUri: manifest.entryPoint,
modules: modules,
sources: sources,
);
}