// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library builtin;
// NOTE: Do not import 'dart:io' in builtin.
import 'dart:async';
import 'dart:collection';
import 'dart:_internal';
import 'dart:isolate';
import 'dart:typed_data';


// Before handling an embedder entrypoint we finalize the setup of the
// dart:_builtin library.
bool _setupCompleted = false;


// The root library (aka the script) is imported into this library. The
// standalone embedder uses this to lookup the main entrypoint in the
// root library's namespace.
Function _getMainClosure() => main;


// 'print' implementation.
// The standalone embedder registers the closurized _print function with the
// dart:core library.
void _printString(String s) native "Builtin_PrintString";


void _print(arg) {
  _printString(arg.toString());
}


_getPrintClosure() => _print;


// Corelib 'Uri.base' implementation.
// Uri.base is susceptible to changes in the current working directory.
_getCurrentDirectoryPath() native "Builtin_GetCurrentDirectory";


Uri _uriBase() {
  // We are not using Dircetory.current here to limit the dependency
  // on dart:io. This code is the same as:
  //   return new Uri.directory(Directory.current.path);
  var path = _getCurrentDirectoryPath();
  return new Uri.directory(path);
}


_getUriBaseClosure() => _uriBase;


// Asynchronous loading of resources.
// The embedder forwards most loading requests to this library.

// See Dart_LibraryTag in dart_api.h
const _Dart_kScriptTag = null;
const _Dart_kImportTag = 0;
const _Dart_kSourceTag = 1;
const _Dart_kCanonicalizeUrl = 2;
const _Dart_kResourceLoad = 3;

// Embedder sets this to true if the --trace-loading flag was passed on the
// command line.
bool _traceLoading = false;

// A port for communicating with the service isolate for I/O.
SendPort _loadPort;
// The receive port for a load request. Multiple sources can be fetched in
// a single load request.
RawReceivePort _dataPort;
// A request id valid only for the current load cycle (while the number of
// outstanding load requests is greater than 0). Can be reset when loading is
// completed.
int _reqId = 0;
// An unordered hash map mapping from request id to a particular load request.
// Once there are no outstanding load requests the current load has finished.
HashMap _reqMap = new HashMap();

// The current working directory when the embedder was launched.
Uri _workingDirectory;
// The URI that the root script was loaded from. Remembered so that
// package imports can be resolved relative to it. The root script is the basis
// for the root library in the VM.
Uri _rootScript;

// Packages are either resolved looking up in a map or resolved from within a
// package root.
bool get _packagesReady =>
    (_packageRoot != null) || (_packageMap != null) || (_packageError != null);
// Error string set if there was an error resolving package configuration.
// For example not finding a .packages file or packages/ directory, malformed
// .packages file or any other related error.
String _packageError = null;
// The directory to look in to resolve "package:" scheme URIs. By detault it is
// the 'packages' directory right next to the script.
Uri _packageRoot = null; // Used to be _rootScript.resolve('packages/');
// The map describing how certain package names are mapped to Uris.
Uri _packageConfig = null;
Map<String, Uri> _packageMap = null;

// A list of pending packags which have been requested while resolving the
// location of the package root or the contents of the package map.
List<_LoadRequest> _pendingPackageLoads = [];

// If we have outstanding loads or pending package loads waiting for resolution,
// then we do have pending loads.
bool _pendingLoads() => !_reqMap.isEmpty || !_pendingPackageLoads.isEmpty;

// Special handling for Windows paths so that they are compatible with URI
// handling.
// Embedder sets this to true if we are running on Windows.
bool _isWindows = false;

// Logging from builtin.dart is prefixed with a '*'.
String _logId = (Isolate.current.hashCode % 0x100000).toRadixString(16);
_log(msg) {
  _print("* $_logId $msg");
}

// A class wrapping the load error message in an Error object.
class _LoadError extends Error {
  final _LoadRequest request;
  final String message;
  _LoadError(this.request, this.message);

  String toString() {
    var context = request._context;
    if (context == null || context is! String) {
      return 'Could not load "${request._uri}": $message';
    } else {
      return 'Could not import "${request._uri}" from "$context": $message';
    }
  }
}

// Class collecting all of the information about a particular load request.
class _LoadRequest {
  final int _id = _reqId++;
  final int _tag;
  final String _uri;
  final Uri _resourceUri;
  final _context;

  _LoadRequest(this._tag, this._uri, this._resourceUri, this._context) {
    assert(_reqMap[_id] == null);
    _reqMap[_id] = this;
  }

  toString() => "LoadRequest($_id, $_tag, $_uri, $_resourceUri, $_context)";
}


// Native calls provided by the embedder.
void _signalDoneLoading() native "Builtin_DoneLoading";
void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data)
    native "Builtin_LoadSource";
void _asyncLoadErrorCallback(uri, libraryUri, error)
    native "Builtin_AsyncLoadError";


_sanitizeWindowsPath(path) {
  // For Windows we need to massage the paths a bit according to
  // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
  //
  // Convert
  // C:\one\two\three
  // to
  // /C:/one/two/three

  if (_isWindows == false) {
    // Do nothing when not running Windows.
    return path;
  }

  var fixedPath = "${path.replaceAll('\\', '/')}";

  if ((path.length > 2) && (path[1] == ':')) {
    // Path begins with a drive letter.
    return '/$fixedPath';
  }

  return fixedPath;
}


_trimWindowsPath(path) {
  // Convert /X:/ to X:/.
  if (_isWindows == false) {
    // Do nothing when not running Windows.
    return path;
  }
  if (!path.startsWith('/') || (path.length < 3)) {
    return path;
  }
  // Match '/?:'.
  if ((path[0] == '/') && (path[2] == ':')) {
    // Remove leading '/'.
    return path.substring(1);
  }
  return path;
}


// Ensure we have a trailing slash character.
_enforceTrailingSlash(uri) {
  if (!uri.endsWith('/')) {
    return '$uri/';
  }
  return uri;
}


// Embedder Entrypoint:
// The embedder calls this method with the current working directory.
void _setWorkingDirectory(cwd) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  if (_traceLoading) {
    _log('Setting working directory: $cwd');
  }
  _workingDirectory = new Uri.directory(cwd);
  if (_traceLoading) {
    _log('Working directory URI: $_workingDirectory');
  }
}


// Embedder Entrypoint:
// The embedder calls this method with a custom package root.
_setPackageRoot(String packageRoot) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  if (_traceLoading) {
    _log('Setting package root: $packageRoot');
  }
  packageRoot = _enforceTrailingSlash(packageRoot);
  if (packageRoot.startsWith('file:') ||
      packageRoot.startsWith('http:') ||
      packageRoot.startsWith('https:')) {
    _packageRoot = _workingDirectory.resolve(packageRoot);
  } else {
    packageRoot = _sanitizeWindowsPath(packageRoot);
    packageRoot = _trimWindowsPath(packageRoot);
    _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
  }
  // Now that we have determined the packageRoot value being used, set it
  // up for use in Platform.packageRoot. This is only set when the embedder
  // sets up the package root. Automatically discovered package root will
  // not update the VMLibraryHooks value.
  VMLibraryHooks.packageRootString = _packageRoot.toString();
  if (_traceLoading) {
    _log('Package root URI: $_packageRoot');
  }
}


// Given a uri with a 'package' scheme, return a Uri that is prefixed with
// the package root.
Uri _resolvePackageUri(Uri uri) {
  assert(uri.scheme == "package");
  assert(_packagesReady);

  if (!uri.host.isEmpty) {
    var path = '${uri.host}${uri.path}';
    var right = 'package:$path';
    var wrong = 'package://$path';

    throw "URIs using the 'package:' scheme should look like "
          "'$right', not '$wrong'.";
  }

  if (_traceLoading) {
    _log('Resolving package with uri path: ${uri.path}');
  }
  var resolvedUri;
  if (_packageError != null) {
    if (_traceLoading) {
      _log("Resolving package with pending resolution error: $_packageError");
    }
    throw _packageError;
  } else if (_packageRoot != null) {
    resolvedUri = _packageRoot.resolve(uri.path);
  } else {
    var packageName = uri.pathSegments[0];
    var mapping = _packageMap[packageName];
    if (_traceLoading) {
      _log("Mapped '$packageName' package to '$mapping'");
    }
    if (mapping == null) {
      throw "No mapping for '$packageName' package when resolving '$uri'.";
    }
    var path = uri.path.substring(packageName.length + 1);
    resolvedUri = mapping.resolve(path);
  }
  if (_traceLoading) {
    _log("Resolved '$uri' to '$resolvedUri'.");
  }
  return resolvedUri;
}


// Resolves the script uri in the current working directory iff the given uri
// did not specify a scheme (e.g. a path to a script file on the command line).
Uri _resolveScriptUri(String scriptName) {
  if (_traceLoading) {
    _log("Resolving script: $scriptName");
  }
  if (_workingDirectory == null) {
    throw 'No current working directory set.';
  }
  scriptName = _sanitizeWindowsPath(scriptName);

  var scriptUri = Uri.parse(scriptName);
  if (scriptUri.scheme == '') {
    // Script does not have a scheme, assume that it is a path,
    // resolve it against the working directory.
    scriptUri = _workingDirectory.resolveUri(scriptUri);
  }

  // Remember the root script URI so that we can resolve packages based on
  // this location.
  _rootScript = scriptUri;

  if (_traceLoading) {
    _log('Resolved entry point to: $_rootScript');
  }
  return scriptUri;
}


void _finishLoadRequest(_LoadRequest req) {
  if (req != null) {
    // Now that we are done with loading remove the request from the map.
    var tmp = _reqMap.remove(req._id);
    assert(tmp == req);
    if (_traceLoading) {
      _log("Loading of ${req._uri} finished: "
           "${_reqMap.length} requests remaining, "
           "${_pendingPackageLoads.length} packages pending.");
    }
  }

  if (!_pendingLoads() && (_dataPort != null)) {
    // Close the _dataPort now that there are no more requests outstanding.
    if (_traceLoading) {
      _log("Closing loading port.");
    }
    _dataPort.close();
    _dataPort = null;
    _reqId = 0;
    _signalDoneLoading();
  }
}


void _handleLoaderReply(msg) {
  int id = msg[0];
  var dataOrError = msg[1];
  assert((id >= 0) && (id < _reqId));
  var req = _reqMap[id];
  try {
    if (dataOrError is Uint8List) {
      // Successfully loaded the data.
      if (req._tag == _Dart_kResourceLoad) {
        Completer c = req._context;
        c.complete(dataOrError);
      } else {
        // TODO: Currently a compilation error while loading the script is
        // fatal for the isolate. _loadScriptCallback() does not return and
        // the number of requests remains out of sync.
        _loadScriptCallback(req._tag, req._uri, req._context, dataOrError);
      }
      _finishLoadRequest(req);
    } else {
      assert(dataOrError is String);
      var error = new _LoadError(req, dataOrError.toString());
      _asyncLoadError(req, error, null);
    }
  } catch(e, s) {
    // Wrap inside a _LoadError unless we are already propagating a
    // previous _LoadError.
    var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
    assert(req != null);
    _asyncLoadError(req, error, s);
  }
}


void _startLoadRequest(int tag, String uri, Uri resourceUri, context) {
  if (_dataPort == null) {
    if (_traceLoading) {
      _log("Initializing load port.");
    }
    assert(_dataPort == null);
    _dataPort = new RawReceivePort(_handleLoaderReply);
  }
  // Register the load request and send it to the VM service isolate.
  var req = new _LoadRequest(tag, uri, resourceUri, context);

  assert(_dataPort != null);
  var msg = new List(4);
  msg[0] = _dataPort.sendPort;
  msg[1] = _traceLoading;
  msg[2] = req._id;
  msg[3] = resourceUri.toString();
  _loadPort.send(msg);

  if (_traceLoading) {
    _log("Loading of $resourceUri for $uri started with id: ${req._id}. "
         "${_reqMap.length} requests remaining, "
         "${_pendingPackageLoads.length} packages pending.");
  }
}


RawReceivePort _packagesPort;

void _handlePackagesReply(msg) {
  // Make sure to close the _packagePort before any other action.
  _packagesPort.close();
  _packagesPort = null;

  if (_traceLoading) {
    _log("Got packages reply: $msg");
  }
  if (msg is String) {
    if (_traceLoading) {
      _log("Got failure response on package port: '$msg'");
    }
    // Remember the error message.
    _packageError = msg;
  } else if (msg is List) {
    if (msg.length == 1) {
      if (_traceLoading) {
        _log("Received package root: '${msg[0]}'");
      }
      _packageRoot = Uri.parse(msg[0]);
    } else {
      // First entry contains the location of the loaded .packages file.
      assert((msg.length % 2) == 0);
      assert(msg.length >= 2);
      assert(msg[1] == null);
      _packageConfig = Uri.parse(msg[0]);
      _packageMap = new Map<String, Uri>();
      for (var i = 2; i < msg.length; i+=2) {
        // TODO(iposva): Complain about duplicate entries.
        _packageMap[msg[i]] = Uri.parse(msg[i+1]);
      }
      if (_traceLoading) {
        _log("Setup package map: $_packageMap");
      }
    }
  } else {
    _packageError = "Bad type of packages reply: ${msg.runtimeType}";
    if (_traceLoading) {
      _log(_packageError);
    }
  }

  // Resolve all pending package loads now that we know how to resolve them.
  while (_pendingPackageLoads.length > 0) {
    // Order does not matter as we queue all of the requests up right now.
    var req = _pendingPackageLoads.removeLast();
    // Call the registered closure, to handle the delayed action.
    req();
  }
  // Reset the pending package loads to empty. So that we eventually can
  // finish loading.
  _pendingPackageLoads = [];
  // Make sure that the receive port is closed if no other loads are pending.
  _finishLoadRequest(null);
}


void _requestPackagesMap() {
  assert(_packagesPort == null);
  assert(_rootScript != null);
  // Create a port to receive the packages map on.
  _packagesPort = new RawReceivePort(_handlePackagesReply);
  var sp = _packagesPort.sendPort;

  var msg = new List(4);
  msg[0] = sp;
  msg[1] = _traceLoading;
  msg[2] = -1;
  msg[3] = _rootScript.toString();
  _loadPort.send(msg);

  if (_traceLoading) {
    _log("Requested packages map for '$_rootScript'.");
  }
}


// Embedder Entrypoint:
// Request the load of a particular packages map.
void _loadPackagesMap(String packagesParam) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  // First convert the packages parameter from the command line to a URI which
  // can be handled by the loader code.
  // TODO(iposva): Consider refactoring the common code below which is almost
  // shared with resolution of the root script.
  if (_traceLoading) {
    _log("Resolving packages map: $packagesParam");
  }
  if (_workingDirectory == null) {
    throw 'No current working directory set.';
  }
  var packagesName = _sanitizeWindowsPath(packagesParam);
  var packagesUri = Uri.parse(packagesName);
  if (packagesUri.scheme == '') {
    // Script does not have a scheme, assume that it is a path,
    // resolve it against the working directory.
    packagesUri = _workingDirectory.resolveUri(packagesUri);
  }
  var packagesUriStr = packagesUri.toString();
  VMLibraryHooks.packageConfigString = packagesUriStr;
  if (_traceLoading) {
    _log('Resolved packages map to: $packagesUri');
  }

  // Request the loading and parsing of the packages map at the specified URI.
  // Create a port to receive the packages map on.
  assert(_packagesPort == null);
  _packagesPort = new RawReceivePort(_handlePackagesReply);
  var sp = _packagesPort.sendPort;

  var msg = new List(4);
  msg[0] = sp;
  msg[1] = _traceLoading;
  msg[2] = -2;
  msg[3] = packagesUriStr;
  _loadPort.send(msg);

  // Signal that the resolution of the packages map has started. But in this
  // case it is not tied to a particular request.
  _pendingPackageLoads.add(() {
    // Nothing to be done beyond registering that there is pending package
    // resolution requested by having an empty entry.
    if (_traceLoading) {
      _log("Skipping dummy deferred request.");
    }
  });

  if (_traceLoading) {
    _log("Requested packages map at '$packagesUri'.");
  }
}


void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) {
  if (_traceLoading) {
    _log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack");
  }
  if (req._tag == _Dart_kResourceLoad) {
    Completer c = req._context;
    c.completeError(error, stack);
  } else {
    String libraryUri = req._context;
    if (req._tag == _Dart_kImportTag) {
      // When importing a library, the libraryUri is the imported
      // uri.
      libraryUri = req._uri;
    }
    _asyncLoadErrorCallback(req._uri, libraryUri, error);
  }
  _finishLoadRequest(req);
}


_loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) {
  try {
    _startLoadRequest(tag, uri, resourceUri, context);
  } catch (e, s) {
    if (_traceLoading) {
      _log("Exception when communicating with service isolate: $e");
    }
    // Register a dummy load request so we can fail to load it.
    var req = new _LoadRequest(tag, uri, resourceUri, context);

    // Wrap inside a _LoadError unless we are already propagating a previously
    // seen _LoadError.
    var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
    _asyncLoadError(req, error, s);
  }
}


// Loading a package URI needs to first map the package name to a loadable
// URI.
_loadPackage(int tag, String uri, Uri resourceUri, context) {
  if (_packagesReady) {
    var resolvedUri;
    try {
      resolvedUri = _resolvePackageUri(resourceUri);
    } catch (e, s) {
      if (_traceLoading) {
        _log("Exception ($e) when resolving package URI: $resourceUri");
      }
      // Register a dummy load request so we can fail to load it.
      var req = new _LoadRequest(tag, uri, resourceUri, context);

      // Wrap inside a _LoadError unless we are already propagating a previously
      // seen _LoadError.
      var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
      _asyncLoadError(req, error, s);
    }
    _loadData(tag, uri, resolvedUri, context);
  } else {
    if (_pendingPackageLoads.isEmpty) {
      // Package resolution has not been setup yet, and this is the first
      // request for package resolution & loading.
      _requestPackagesMap();
    }
    // Register the action of loading this package once the package resolution
    // is ready.
    _pendingPackageLoads.add(() {
      if (_traceLoading) {
        _log("Handling deferred package request: "
             "$tag, $uri, $resourceUri, $context");
      }
      _loadPackage(tag, uri, resourceUri, context);
    });
    if (_traceLoading) {
      _log("Pending package load of '$uri': "
           "${_pendingPackageLoads.length} pending");
    }
  }
}


// Load the data associated with the resourceUri.
_loadData(int tag, String uri, Uri resourceUri, context) {
  if (resourceUri.scheme == 'package') {
    // package based uris need to be resolved to the correct loadable location.
    // The logic of which is handled seperately, and then _loadData is called
    // recursively.
    _loadPackage(tag, uri, resourceUri, context);
  } else {
    _loadDataFromLoadPort(tag, uri, resourceUri, context);
  }
}


// Embedder Entrypoint:
// Asynchronously loads script data through a http[s] or file uri.
_loadDataAsync(int tag, String uri, String libraryUri) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  var resourceUri;
  if (tag == _Dart_kScriptTag) {
    resourceUri = _resolveScriptUri(uri);
    uri = resourceUri.toString();
  } else {
    resourceUri = Uri.parse(uri);
  }
  _loadData(tag, uri, resourceUri, libraryUri);
}


// Embedder Entrypoint:
// Function called by standalone embedder to resolve uris when the VM requests
// Dart_kCanonicalizeUrl from the tag handler.
String _resolveUri(String base, String userString) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  if (_traceLoading) {
    _log('Resolving: $userString from $base');
  }
  var baseUri = Uri.parse(base);
  var result;
  if (userString.startsWith(_DART_EXT)) {
    var uri = userString.substring(_DART_EXT.length);
    result = '$_DART_EXT${baseUri.resolve(uri)}';
  } else {
    result = baseUri.resolve(userString).toString();
  }
  if (_traceLoading) {
    _log('Resolved $userString in $base to $result');
  }
  return result;
}


// Handling of access to the package root or package map from user code.
_triggerPackageResolution(action) {
  if (_packagesReady) {
    // Packages are ready. Execute the action now.
    action();
  } else {
    if (_pendingPackageLoads.isEmpty) {
      // Package resolution has not been setup yet, and this is the first
      // request for package resolution & loading.
      _requestPackagesMap();
    }
    // Register the action for when the package resolution is ready.
    _pendingPackageLoads.add(action);
  }
}


Future<Uri> _getPackageRootFuture() {
  if (_traceLoading) {
    _log("Request for package root from user code.");
  }
  var completer = new Completer<Uri>();
  _triggerPackageResolution(() {
    completer.complete(_packageRoot);
  });
  return completer.future;
}


Future<Uri> _getPackageConfigFuture() {
  if (_traceLoading) {
    _log("Request for package config from user code.");
  }
  var completer = new Completer<Uri>();
  _triggerPackageResolution(() {
    completer.complete(_packageConfig);
  });
  return completer.future;
}


Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
  if (_traceLoading) {
    _log("Request for package Uri resolution from user code: $packageUri");
  }
  if (packageUri.scheme != "package") {
    if (_traceLoading) {
      _log("Non-package Uri, returning unmodified: $packageUri");
    }
    // Return the incoming parameter if not passed a package: URI.
    return packageUri;
  }

  if (!_packagesReady) {
    if (_traceLoading) {
      _log("Trigger loading by requesting the package config.");
    }
    // Make sure to trigger package resolution.
    var dummy = await _getPackageConfigFuture();
  }
  assert(_packagesReady);

  var result = _resolvePackageUri(packageUri);
  if (_traceLoading) {
    _log("Resolved '$packageUri' to '$result'");
  }
  return result;
}


// Handling of Resource class by dispatching to the load port.
Future<List<int>> _resourceReadAsBytes(Uri uri) {
  var completer = new Completer<List<int>>();
  // Request the load of the resource associating the completer as the context
  // for the load.
  _loadData(_Dart_kResourceLoad, uri.toString(), uri, completer);
  // Return the future that will be triggered once the resource has been loaded.
  return completer.future;
}


// Embedder Entrypoint (gen_snapshot):
// Resolve relative paths relative to working directory.
String _resolveInWorkingDirectory(String fileName) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  if (_workingDirectory == null) {
    throw 'No current working directory set.';
  }
  var name = _sanitizeWindowsPath(fileName);

  var uri = Uri.parse(name);
  if (uri.scheme != '') {
    throw 'Schemes are not supported when resolving filenames.';
  }
  uri = _workingDirectory.resolveUri(uri);

  if (_traceLoading) {
    _log('Resolved in working directory: $fileName -> $uri');
  }
  return uri.toString();
}


// Handling of dart-ext loading.
// Dart native extension scheme.
const _DART_EXT = 'dart-ext:';

String _nativeLibraryExtension() native "Builtin_NativeLibraryExtension";


String _platformExtensionFileName(String name) {
  var extension = _nativeLibraryExtension();

  if (_isWindows) {
    return '$name.$extension';
  } else {
    return 'lib$name.$extension';
  }
}


// Returns either a file path or a URI starting with http[s]:, as a String.
String _filePathFromUri(String userUri) {
  var uri = Uri.parse(userUri);
  if (_traceLoading) {
    _log('Getting file path from: $uri');
  }

  var path;
  switch (uri.scheme) {
    case '':
    case 'file':
    return uri.toFilePath();
    case 'package':
    return _filePathFromUri(_resolvePackageUri(uri).toString());
    case 'data':
    case 'http':
    case 'https':
    return uri.toString();
    default:
    // Only handling file, http, and package URIs
    // in standalone binary.
    if (_traceLoading) {
      _log('Unknown scheme (${uri.scheme}) in $uri.');
    }
    throw 'Not a known scheme: $uri';
  }
}


// Embedder Entrypoint:
// When loading an extension the embedder calls this method to get the
// different components.
// Returns the directory part, the filename part, and the name
// of a native extension URL as a list [directory, filename, name].
// The directory part is either a file system path or an HTTP(S) URL.
// The filename part is the extension name, with the platform-dependent
// prefixes and extensions added.
_extensionPathFromUri(String userUri) {
  if (!_setupCompleted) {
    _setupHooks();
  }
  if (!userUri.startsWith(_DART_EXT)) {
    throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:';
  }
  userUri = userUri.substring(_DART_EXT.length);

  if (userUri.contains('\\')) {
    throw 'Unexpected internal error: Extension URI $userUri contains \\';
  }

  String name;
  String path;  // Will end in '/'.
  int index = userUri.lastIndexOf('/');
  if (index == -1) {
    name = userUri;
    path = './';
  } else if (index == userUri.length - 1) {
    throw 'Extension name missing in $extensionUri';
  } else {
    name = userUri.substring(index + 1);
    path = userUri.substring(0, index + 1);
  }

  path = _filePathFromUri(path);
  var filename = _platformExtensionFileName(name);

  return [path, filename, name];
}


// Register callbacks and hooks with the rest of the core libraries.
_setupHooks() {
  _setupCompleted = true;
  VMLibraryHooks.resourceReadAsBytes = _resourceReadAsBytes;

  VMLibraryHooks.packageRootUriFuture = _getPackageRootFuture;
  VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
  VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
}
