// 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.

part of dart.core;

// Frequently used character codes.
const int _SPACE = 0x20;
const int _PERCENT = 0x25;
const int _AMPERSAND = 0x26;
const int _PLUS = 0x2B;
const int _DOT = 0x2E;
const int _SLASH = 0x2F;
const int _COLON = 0x3A;
const int _EQUALS = 0x3d;
const int _UPPER_CASE_A = 0x41;
const int _UPPER_CASE_Z = 0x5A;
const int _LEFT_BRACKET = 0x5B;
const int _BACKSLASH = 0x5C;
const int _RIGHT_BRACKET = 0x5D;
const int _LOWER_CASE_A = 0x61;
const int _LOWER_CASE_F = 0x66;
const int _LOWER_CASE_Z = 0x7A;

const String _hexDigits = "0123456789ABCDEF";

/// A parsed URI, such as a URL.
///
/// To create a URI with specific components, use [Uri.new]:
/// ```dart
/// var httpsUri = Uri(
///     scheme: 'https',
///     host: 'dart.dev',
///     path: '/guides/libraries/library-tour',
///     fragment: 'numbers');
/// print(httpsUri); // https://dart.dev/guides/libraries/library-tour#numbers
///
/// httpsUri = Uri(
///     scheme: 'https',
///     host: 'example.com',
///     path: '/page/',
///     queryParameters: {'search': 'blue', 'limit': '10'});
/// print(httpsUri); // https://example.com/page/?search=blue&limit=10
///
/// final mailtoUri = Uri(
///     scheme: 'mailto',
///     path: 'John.Doe@example.com',
///     queryParameters: {'subject': 'Example'});
/// print(mailtoUri); // mailto:John.Doe@example.com?subject=Example
/// ```
///
/// ## HTTP and HTTPS URI
/// To create a URI with https scheme, use [Uri.https] or [Uri.http]:
/// ```dart
/// final httpsUri = Uri.https('example.com', 'api/fetch', {'limit': '10'});
/// print(httpsUri); // https://example.com/api/fetch?limit=10
/// ```
/// ## File URI
/// To create a URI from file path, use [Uri.file]:
/// ```dart
/// final fileUriUnix =
///     Uri.file(r'/home/myself/images/image.png', windows: false);
/// print(fileUriUnix); // file:///home/myself/images/image.png
///
/// final fileUriWindows =
///     Uri.file(r'C:\Users\myself\Documents\image.png', windows: true);
/// print(fileUriWindows); // file:///C:/Users/myself/Documents/image.png
/// ```
/// If the URI is not a file URI, calling this throws [UnsupportedError].
///
/// ## Directory URI
/// Like [Uri.file] except that a non-empty URI path ends in a slash.
/// ```dart
/// final fileDirectory =
///     Uri.directory('/home/myself/data/image', windows: false);
/// print(fileDirectory); // file:///home/myself/data/image/
///
/// final fileDirectoryWindows = Uri.directory('/data/images', windows: true);
/// print(fileDirectoryWindows); //  file:///data/images/
/// ```
///
/// ## URI from string
/// To create a URI from string, use [Uri.parse] or [Uri.tryParse]:
/// ```dart
/// final uri = Uri.parse(
///     'https://dart.dev/guides/libraries/library-tour#utility-classes');
/// print(uri); // https://dart.dev
/// print(uri.isScheme('https')); // true
/// print(uri.origin); // https://dart.dev
/// print(uri.host); // dart.dev
/// print(uri.authority); // dart.dev
/// print(uri.port); // 443
/// print(uri.path); // guides/libraries/library-tour
/// print(uri.pathSegments); // [guides, libraries, library-tour]
/// print(uri.fragment); // utility-classes
/// print(uri.hasQuery); // false
/// print(uri.data); // null
/// ```
///
/// **See also:**
/// * [URIs][uris] in the [library tour][libtour]
/// * [RFC-3986](https://tools.ietf.org/html/rfc3986)
/// * [RFC-2396](https://tools.ietf.org/html/rfc2396)
/// * [RFC-2045](https://tools.ietf.org/html/rfc2045)
///
/// [uris]: https://dart.dev/guides/libraries/library-tour#uris
/// [libtour]: https://dart.dev/guides/libraries/library-tour
abstract interface class Uri {
  /// The natural base URI for the current platform.
  ///
  /// When running in a browser, this is the current URL of the current page
  /// (from `window.location.href`).
  ///
  /// When not running in a browser, this is the file URI referencing
  /// the current working directory.
  external static Uri get base;

  /// Creates a new URI from its components.
  ///
  /// Each component is set through a named argument. Any number of
  /// components can be provided. The [path] and [query] components can be set
  /// using either of two different named arguments.
  ///
  /// The scheme component is set through [scheme]. The scheme is
  /// normalized to all lowercase letters. If the scheme is omitted or empty,
  /// the URI will not have a scheme part.
  ///
  /// The user info part of the authority component is set through
  /// [userInfo]. It defaults to the empty string, which will be omitted
  /// from the string representation of the URI.
  ///
  /// The host part of the authority component is set through
  /// [host]. The host can either be a hostname, an IPv4 address or an
  /// IPv6 address, contained in `'['` and `']'`. If the host contains a
  /// ':' character, the `'['` and `']'` are added if not already provided.
  /// The host is normalized to all lowercase letters.
  ///
  /// The port part of the authority component is set through
  /// [port].
  /// If [port] is omitted or `null`, it implies the default port for
  /// the URI's scheme, and is equivalent to passing that port explicitly.
  /// The recognized schemes, and their default ports, are "http" (80) and
  /// "https" (443). All other schemes are considered as having zero as the
  /// default port.
  ///
  /// If any of `userInfo`, `host` or `port` are provided,
  /// the URI has an authority according to [hasAuthority].
  ///
  /// The path component is set through either [path] or
  /// [pathSegments].
  /// When [path] is used, it should be a valid URI path,
  /// but invalid characters, except the general delimiters ':/@[]?#',
  /// will be escaped if necessary. A backslash, `\`, will be converted
  /// to a slash `/`.
  /// When [pathSegments] is used, each of the provided segments
  /// is first percent-encoded and then joined using the forward slash
  /// separator.
  ///
  /// The percent-encoding of the path segments encodes all
  /// characters except for the unreserved characters and the following
  /// list of characters: `!$&'()*+,;=:@`. If the other components
  /// necessitate an absolute path, a leading slash `/` is prepended if
  /// not already there.
  ///
  /// The query component is set through either [query] or [queryParameters].
  /// When [query] is used, the provided string should be a valid URI query,
  /// but invalid characters, other than general delimiters,
  /// will be escaped if necessary.
  /// When [queryParameters] is used, the query is built from the
  /// provided map. Each key and value in the map is percent-encoded
  /// and joined using equal and ampersand characters.
  /// A value in the map must be either `null`, a string, or an [Iterable] of
  /// strings. An iterable corresponds to multiple values for the same key,
  /// and an empty iterable or `null` corresponds to no value for the key.
  ///
  /// The percent-encoding of the keys and values encodes all characters
  /// except for the unreserved characters, and replaces spaces with `+`.
  /// If [query] is the empty string, it is equivalent to omitting it.
  /// To have an actual empty query part,
  /// use an empty map for [queryParameters].
  ///
  /// If both [query] and [queryParameters] are omitted or `null`,
  /// the URI has no query part.
  ///
  /// The fragment component is set through [fragment].
  /// It should be a valid URI fragment, but invalid characters other than
  /// general delimiters are escaped if necessary.
  /// If [fragment] is omitted or `null`, the URI has no fragment part.
  ///
  /// Example:
  /// ```dart
  /// final httpsUri = Uri(
  ///     scheme: 'https',
  ///     host: 'dart.dev',
  ///     path: 'guides/libraries/library-tour',
  ///     fragment: 'numbers');
  /// print(httpsUri); // https://dart.dev/guides/libraries/library-tour#numbers
  ///
  /// final mailtoUri = Uri(
  ///     scheme: 'mailto',
  ///     path: 'John.Doe@example.com',
  ///     queryParameters: {'subject': 'Example'});
  /// print(mailtoUri); // mailto:John.Doe@example.com?subject=Example
  /// ```
  factory Uri({
    String? scheme,
    String? userInfo,
    String? host,
    int? port,
    String? path,
    Iterable<String>? pathSegments,
    String? query,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
    String? fragment,
  }) = _Uri;

  /// Creates a new `http` URI from authority, path and query.
  ///
  /// Example:
  /// ```dart
  /// var uri = Uri.http('example.org', '/path', { 'q' : 'dart' });
  /// print(uri); // http://example.org/path?q=dart
  ///
  /// uri = Uri.http('user:password@localhost:8080', '');
  /// print(uri); // http://user:password@localhost:8080
  ///
  /// uri = Uri.http('example.org', 'a b');
  /// print(uri); // http://example.org/a%20b
  ///
  /// uri = Uri.http('example.org', '/a%2F');
  /// print(uri); // http://example.org/a%252F
  /// ```
  ///
  /// The `scheme` is always set to `http`.
  ///
  /// The `userInfo`, `host` and `port` components are set from the
  /// [authority] argument. If `authority` is `null` or empty,
  /// the created `Uri` has no authority, and isn't directly usable
  /// as an HTTP URL, which must have a non-empty host.
  ///
  /// The `path` component is set from the [unencodedPath]
  /// argument. The path passed must not be encoded as this constructor
  /// encodes the path. Only `/` is recognized as path separator.
  /// If omitted, the path defaults to being empty.
  ///
  /// The `query` component is set from the optional [queryParameters]
  /// argument.
  factory Uri.http(
    String authority, [
    String unencodedPath,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
  ]) = _Uri.http;

  /// Creates a new `https` URI from authority, path and query.
  ///
  /// This constructor is the same as [Uri.http] except for the scheme
  /// which is set to `https`.
  ///
  /// Example:
  /// ```dart
  /// var uri = Uri.https('example.org', '/path', {'q': 'dart'});
  /// print(uri); // https://example.org/path?q=dart
  ///
  /// uri = Uri.https('user:password@localhost:8080', '');
  /// print(uri); // https://user:password@localhost:8080
  ///
  /// uri = Uri.https('example.org', 'a b');
  /// print(uri); // https://example.org/a%20b
  ///
  /// uri = Uri.https('example.org', '/a%2F');
  /// print(uri); // https://example.org/a%252F
  /// ```
  factory Uri.https(
    String authority, [
    String unencodedPath,
    Map<String, dynamic>? queryParameters,
  ]) = _Uri.https;

  /// Creates a new file URI from an absolute or relative file path.
  ///
  /// The file path is passed in [path].
  ///
  /// This path is interpreted using either Windows or non-Windows
  /// semantics.
  ///
  /// With non-Windows semantics, the slash (`/`) is used to separate
  /// path segments in the input [path].
  ///
  /// With Windows semantics, backslash (`\`) and forward-slash (`/`)
  /// are used to separate path segments in the input [path],
  /// except if the path starts with `\\?\` in which case
  /// only backslash (`\`) separates path segments in [path].
  ///
  /// If the path starts with a path separator, an absolute URI (with the
  /// `file` scheme and an empty authority) is created.
  /// Otherwise a relative URI reference with no scheme or authority is created.
  /// One exception to this rule is that when Windows semantics is used
  /// and the path starts with a drive letter followed by a colon (":") and a
  /// path separator, then an absolute URI is created.
  ///
  /// The default for whether to use Windows or non-Windows semantics
  /// is determined from the platform Dart is running on. When running in
  /// the standalone VM, this is detected by the VM based on the
  /// operating system. When running in a browser, non-Windows semantics
  /// is always used.
  ///
  /// To override the automatic detection of which semantics to use pass
  /// a value for [windows]. Passing `true` will use Windows
  /// semantics and passing `false` will use non-Windows semantics.
  ///
  /// Examples using non-Windows semantics:
  /// ```dart
  /// // xxx/yyy
  /// Uri.file('xxx/yyy', windows: false);
  ///
  /// // xxx/yyy/
  /// Uri.file('xxx/yyy/', windows: false);
  ///
  /// // file:///xxx/yyy
  /// Uri.file('/xxx/yyy', windows: false);
  ///
  /// // file:///xxx/yyy/
  /// Uri.file('/xxx/yyy/', windows: false);
  ///
  /// // C%3A
  /// Uri.file('C:', windows: false);
  /// ```
  ///
  /// Examples using Windows semantics:
  /// ```dart
  /// // xxx/yyy
  /// Uri.file(r'xxx\yyy', windows: true);
  ///
  /// // xxx/yyy/
  /// Uri.file(r'xxx\yyy\', windows: true);
  ///
  /// file:///xxx/yyy
  /// Uri.file(r'\xxx\yyy', windows: true);
  ///
  /// file:///xxx/yyy/
  /// Uri.file(r'\xxx\yyy/', windows: true);
  ///
  /// // file:///C:/xxx/yyy
  /// Uri.file(r'C:\xxx\yyy', windows: true);
  ///
  /// // This throws an error. A path with a drive letter, but no following
  /// // path, is not allowed.
  /// Uri.file(r'C:', windows: true);
  ///
  /// // This throws an error. A path with a drive letter is not absolute.
  /// Uri.file(r'C:xxx\yyy', windows: true);
  ///
  /// // file://server/share/file
  /// Uri.file(r'\\server\share\file', windows: true);
  /// ```
  ///
  /// If the path passed is not a valid file path, an error is thrown.
  factory Uri.file(String path, {bool? windows}) = _Uri.file;

  /// Like [Uri.file] except that a non-empty URI path ends in a slash.
  ///
  /// If [path] is not empty, and it doesn't end in a directory separator,
  /// then a slash is added to the returned URI's path.
  /// In all other cases, the result is the same as returned by `Uri.file`.
  ///
  /// Example:
  /// ```dart
  /// final fileDirectory = Uri.directory('data/images', windows: false);
  /// print(fileDirectory); // data/images/
  ///
  /// final fileDirectoryWindows =
  ///    Uri.directory(r'C:\data\images', windows: true);
  /// print(fileDirectoryWindows); // file:///C:/data/images/
  /// ```
  factory Uri.directory(String path, {bool? windows}) = _Uri.directory;

  /// Creates a `data:` URI containing the [content] string.
  ///
  /// Converts the content to bytes using [encoding] or the charset specified
  /// in [parameters] (defaulting to US-ASCII if not specified or unrecognized),
  /// then encodes the bytes into the resulting data URI.
  ///
  /// Defaults to encoding using percent-encoding (any non-ASCII or
  /// non-URI-valid bytes is replaced by a percent encoding). If [base64] is
  /// true, the bytes are instead encoded using [base64].
  ///
  /// If [encoding] is not provided and [parameters] has a `charset` entry,
  /// that name is looked up using [Encoding.getByName],
  /// and if the lookup returns an encoding, that encoding is used to convert
  /// [content] to bytes.
  /// If providing both an [encoding] and a charset in [parameters], they should
  /// agree, otherwise decoding won't be able to use the charset parameter
  /// to determine the encoding.
  ///
  /// If [mimeType] and/or [parameters] are supplied, they are added to the
  /// created URI. If any of these contain characters that are not allowed
  /// in the data URI, the character is percent-escaped. If the character is
  /// non-ASCII, it is first UTF-8 encoded and then the bytes are percent
  /// encoded. An omitted [mimeType] in a data URI means `text/plain`, just
  /// as an omitted `charset` parameter defaults to meaning `US-ASCII`.
  ///
  /// To read the content back, use [UriData.contentAsString].
  ///
  /// Example:
  /// ```dart
  /// final uri = Uri.dataFromString(
  ///   'example content',
  ///   mimeType: 'text/plain',
  ///   parameters: <String, String>{'search': 'file', 'max': '10'},
  /// );
  /// print(uri); // data:;search=name;max=10,example%20content
  /// ```
  factory Uri.dataFromString(
    String content, {
    String? mimeType,
    Encoding? encoding,
    Map<String, String>? parameters,
    bool base64 = false,
  }) {
    UriData data = UriData.fromString(
      content,
      mimeType: mimeType,
      encoding: encoding,
      parameters: parameters,
      base64: base64,
    );
    return data.uri;
  }

  /// Creates a `data:` URI containing an encoding of [bytes].
  ///
  /// Defaults to Base64 encoding the bytes, but if [percentEncoded]
  /// is `true`, the bytes will instead be percent encoded (any non-ASCII
  /// or non-valid-ASCII-character byte is replaced by a percent encoding).
  ///
  /// To read the bytes back, use [UriData.contentAsBytes].
  ///
  /// It defaults to having the mime-type `application/octet-stream`.
  /// The [mimeType] and [parameters] are added to the created URI.
  /// If any of these contain characters that are not allowed
  /// in the data URI, the character is percent-escaped. If the character is
  /// non-ASCII, it is first UTF-8 encoded and then the bytes are percent
  /// encoded.
  ///
  /// Example:
  /// ```dart
  /// final uri = Uri.dataFromBytes([68, 97, 114, 116]);
  /// print(uri); // data:application/octet-stream;base64,RGFydA==
  /// ```
  factory Uri.dataFromBytes(
    List<int> bytes, {
    String mimeType = "application/octet-stream",
    Map<String, String>? parameters,
    bool percentEncoded = false,
  }) {
    UriData data = UriData.fromBytes(
      bytes,
      mimeType: mimeType,
      parameters: parameters,
      percentEncoded: percentEncoded,
    );
    return data.uri;
  }

  /// The scheme component of the URI.
  ///
  /// The value is the empty string if there is no scheme component.
  ///
  /// A URI scheme is case insensitive.
  /// The returned scheme is canonicalized to lowercase letters.
  String get scheme;

  /// The authority component.
  ///
  /// The authority is formatted from the [userInfo], [host] and [port]
  /// parts.
  ///
  /// The value is the empty string if there is no authority component.
  String get authority;

  /// The user info part of the authority component.
  ///
  /// The value is the empty string if there is no user info in the
  /// authority component.
  String get userInfo;

  /// The host part of the authority component.
  ///
  /// The value is the empty string if there is no authority component and
  /// hence no host.
  ///
  /// If the host is an IP version 6 address, the surrounding `[` and `]` is
  /// removed.
  ///
  /// The host string is case-insensitive.
  /// The returned host name is canonicalized to lower-case
  /// with upper-case percent-escapes.
  String get host;

  /// The port part of the authority component.
  ///
  /// The value is the default port if there is no port number in the authority
  /// component. That's 80 for http, 443 for https, and 0 for everything else.
  int get port;

  /// The path component.
  ///
  /// The path is the actual substring of the URI representing the path,
  /// and it is encoded where necessary. To get direct access to the decoded
  /// path, use [pathSegments].
  ///
  /// The path value is the empty string if there is no path component.
  String get path;

  /// The query component.
  ///
  /// The value is the actual substring of the URI representing the query part,
  /// and it is encoded where necessary.
  /// To get direct access to the decoded query, use [queryParameters].
  ///
  /// The value is the empty string if there is no query component.
  String get query;

  /// The fragment identifier component.
  ///
  /// The value is the empty string if there is no fragment identifier
  /// component.
  String get fragment;

  /// The URI path split into its segments.
  ///
  /// Each of the segments in the list has been decoded.
  /// If the path is empty, the empty list will
  /// be returned. A leading slash `/` does not affect the segments returned.
  ///
  /// The list is unmodifiable and will throw [UnsupportedError] on any
  /// calls that would mutate it.
  List<String> get pathSegments;

  /// The URI query split into a map according to the rules
  /// specified for FORM post in the [HTML 4.01 specification section
  /// 17.13.4](https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
  /// "HTML 4.01 section 17.13.4").
  ///
  /// Each key and value in the resulting map has been decoded.
  /// If there is no query, the empty map is returned.
  ///
  /// Keys in the query string that have no value are mapped to the
  /// empty string.
  /// If a key occurs more than once in the query string, it is mapped to
  /// an arbitrary choice of possible value.
  /// The [queryParametersAll] getter can provide a map
  /// that maps keys to all of their values.
  ///
  /// Example:
  /// ```dart import:convert
  /// final uri =
  ///     Uri.parse('https://example.com/api/fetch?limit=10,20,30&max=100');
  /// print(jsonEncode(uri.queryParameters));
  /// // {"limit":"10,20,30","max":"100"}
  /// ```
  ///
  /// The map is unmodifiable.
  Map<String, String> get queryParameters;

  /// Returns the URI query split into a map according to the rules
  /// specified for FORM post in the [HTML 4.01 specification section
  /// 17.13.4](https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
  /// "HTML 4.01 section 17.13.4").
  ///
  /// Each key and value in the resulting map has been decoded. If there is no
  /// query, the map is empty.
  ///
  /// Keys are mapped to lists of their values. If a key occurs only once,
  /// its value is a singleton list. If a key occurs with no value, the
  /// empty string is used as the value for that occurrence.
  ///
  /// Example:
  /// ```dart import:convert
  /// final uri =
  ///     Uri.parse('https://example.com/api/fetch?limit=10&limit=20&limit=30&max=100');
  /// print(jsonEncode(uri.queryParametersAll)); // {"limit":["10","20","30"],"max":["100"]}
  /// ```
  ///
  /// The map and the lists it contains are unmodifiable.
  Map<String, List<String>> get queryParametersAll;

  /// Whether the URI is absolute.
  ///
  /// A URI is an absolute URI in the sense of RFC 3986 if it has a scheme
  /// and no fragment.
  bool get isAbsolute;

  /// Whether the URI has a [scheme] component.
  bool get hasScheme => scheme.isNotEmpty;

  /// Whether the URI has an [authority] component.
  bool get hasAuthority;

  /// Whether the URI has an explicit port.
  ///
  /// If the port number is the default port number
  /// (zero for unrecognized schemes, with http (80) and https (443) being
  /// recognized),
  /// then the port is made implicit and omitted from the URI.
  bool get hasPort;

  /// Whether the URI has a query part.
  bool get hasQuery;

  /// Whether the URI has a fragment part.
  bool get hasFragment;

  /// Whether the URI has an empty path.
  bool get hasEmptyPath;

  /// Whether the URI has an absolute path (starting with '/').
  bool get hasAbsolutePath;

  /// Returns the origin of the URI in the form scheme://host:port for the
  /// schemes http and https.
  ///
  /// It is an error if the scheme is not "http" or "https", or if the host name
  /// is missing or empty.
  ///
  /// See: https://www.w3.org/TR/2011/WD-html5-20110405/origin-0.html#origin
  String get origin;

  /// Whether the scheme of this [Uri] is [scheme].
  ///
  /// The [scheme] should be the same as the one returned by [Uri.scheme],
  /// but doesn't have to be case-normalized to lower-case characters.
  ///
  /// Example:
  /// ```dart
  /// var uri = Uri.parse('http://example.com');
  /// print(uri.isScheme('HTTP')); // true
  ///
  /// final uriNoScheme = Uri(host: 'example.com');
  /// print(uriNoScheme.isScheme('HTTP')); // false
  /// ```
  ///
  /// An empty [scheme] string matches a URI with no scheme
  /// (one where [hasScheme] returns false).
  bool isScheme(String scheme);

  /// Creates a file path from a file URI.
  ///
  /// The returned path has either Windows or non-Windows
  /// semantics.
  ///
  /// For non-Windows semantics, the slash ("/") is used to separate
  /// path segments.
  ///
  /// For Windows semantics, the backslash ("\\") separator is used to
  /// separate path segments.
  ///
  /// If the URI is absolute, the path starts with a path separator
  /// unless Windows semantics is used and the first path segment is a
  /// drive letter. When Windows semantics is used, a host component in
  /// the uri in interpreted as a file server and a UNC path is
  /// returned.
  ///
  /// The default for whether to use Windows or non-Windows semantics
  /// is determined from the platform Dart is running on. When running in
  /// the standalone VM, this is detected by the VM based on the
  /// operating system. When running in a browser, non-Windows semantics
  /// is always used.
  ///
  /// To override the automatic detection of which semantics to use pass
  /// a value for [windows]. Passing `true` will use Windows
  /// semantics and passing `false` will use non-Windows semantics.
  ///
  /// If the URI ends with a slash (i.e. the last path component is
  /// empty), the returned file path will also end with a slash.
  ///
  /// With Windows semantics, URIs starting with a drive letter cannot
  /// be relative to the current drive on the designated drive. That is,
  /// for the URI `file:///c:abc` calling `toFilePath` will throw as a
  /// path segment cannot contain colon on Windows.
  ///
  /// Examples using non-Windows semantics (resulting of calling
  /// toFilePath in comment):
  /// ```dart
  /// Uri.parse("xxx/yyy");  // xxx/yyy
  /// Uri.parse("xxx/yyy/");  // xxx/yyy/
  /// Uri.parse("file:///xxx/yyy");  // /xxx/yyy
  /// Uri.parse("file:///xxx/yyy/");  // /xxx/yyy/
  /// Uri.parse("file:///C:");  // /C:
  /// Uri.parse("file:///C:a");  // /C:a
  /// ```
  /// Examples using Windows semantics (resulting URI in comment):
  /// ```dart
  /// Uri.parse("xxx/yyy");  // xxx\yyy
  /// Uri.parse("xxx/yyy/");  // xxx\yyy\
  /// Uri.parse("file:///xxx/yyy");  // \xxx\yyy
  /// Uri.parse("file:///xxx/yyy/");  // \xxx\yyy\
  /// Uri.parse("file:///C:/xxx/yyy");  // C:\xxx\yyy
  /// Uri.parse("file:C:xxx/yyy");  // Throws as a path segment
  ///                               // cannot contain colon on Windows.
  /// Uri.parse("file://server/share/file");  // \\server\share\file
  /// ```
  /// If the URI is not a file URI, calling this throws
  /// [UnsupportedError].
  ///
  /// If the URI cannot be converted to a file path, calling this throws
  /// [UnsupportedError].
  // TODO(lrn): Deprecate and move functionality to File class or similar.
  // The core libraries should not worry about the platform.
  String toFilePath({bool? windows});

  /// Access the structure of a `data:` URI.
  ///
  /// Returns a [UriData] object for `data:` URIs and `null` for all other
  /// URIs.
  /// The [UriData] object can be used to access the media type and data
  /// of a `data:` URI.
  UriData? get data;

  /// Returns a hash code computed as `toString().hashCode`.
  ///
  /// This guarantees that URIs with the same normalized string representation
  /// have the same hash code.
  int get hashCode;

  /// A URI is equal to another URI with the same normalized representation.
  bool operator ==(Object other);

  /// The normalized string representation of the URI.
  String toString();

  /// Creates a new `Uri` based on this one, but with some parts replaced.
  ///
  /// This method takes the same parameters as the [Uri] constructor,
  /// and they have the same meaning.
  ///
  /// At most one of [path] and [pathSegments] must be provided.
  /// Likewise, at most one of [query] and [queryParameters] must be provided.
  ///
  /// Each part that is not provided will default to the corresponding
  /// value from this `Uri` instead.
  ///
  /// This method is different from [Uri.resolve], which overrides in a
  /// hierarchical manner,
  /// and can instead replace each part of a `Uri` individually.
  ///
  /// Example:
  /// ```dart
  /// final uri1 = Uri.parse(
  ///     'http://dart.dev/guides/libraries/library-tour#utility-classes');
  ///
  /// final uri2 = uri1.replace(
  ///     scheme: 'https',
  ///     path: 'guides/libraries/library-tour',
  ///     fragment: 'uris');
  /// print(uri2); // https://dart.dev/guides/libraries/library-tour#uris
  /// ```
  /// This method acts similarly to using the `Uri` constructor with
  /// some of the arguments taken from this `Uri`. Example:
  /// ``` dart continued
  /// final Uri uri3 = Uri(
  ///     scheme: 'https',
  ///     userInfo: uri1.userInfo,
  ///     host: uri1.host,
  ///     port: uri2.port,
  ///     path: '/guides/language/language-tour',
  ///     query: uri1.query,
  ///     fragment: null);
  /// print(uri3); // https://dart.dev/guides/language/language-tour
  /// ```
  /// Using this method can be seen as shorthand for the `Uri` constructor
  /// call above, but may also be slightly faster because the parts taken
  /// from this `Uri` need not be checked for validity again.
  Uri replace({
    String? scheme,
    String? userInfo,
    String? host,
    int? port,
    String? path,
    Iterable<String>? pathSegments,
    String? query,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
    String? fragment,
  });

  /// Creates a `Uri` that differs from this only in not having a fragment.
  ///
  /// If this `Uri` does not have a fragment, it is itself returned.
  ///
  /// Example:
  /// ```dart
  /// final uri =
  ///     Uri.parse('https://example.org:8080/foo/bar#frag').removeFragment();
  /// print(uri); // https://example.org:8080/foo/bar
  /// ```
  Uri removeFragment();

  /// Resolve [reference] as an URI relative to `this`.
  ///
  /// First turn [reference] into a URI using [Uri.parse]. Then resolve the
  /// resulting URI relative to `this`.
  ///
  /// Returns the resolved URI.
  ///
  /// See [resolveUri] for details.
  Uri resolve(String reference);

  /// Resolve [reference] as a URI relative to `this`.
  ///
  /// Returns the resolved URI.
  ///
  /// The algorithm "Transform Reference" for resolving a reference is described
  /// in [RFC-3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5
  /// "RFC-1123").
  ///
  /// Updated to handle the case where the base URI is just a relative path -
  /// that is: when it has no scheme and no authority and the path does not
  /// start with a slash.
  /// In that case, the paths are combined without removing leading "..", and
  /// an empty path is not converted to "/".
  Uri resolveUri(Uri reference);

  /// Returns a URI where the path has been normalized.
  ///
  /// A normalized path does not contain `.` segments or non-leading `..`
  /// segments.
  /// Only a relative path with no scheme or authority may contain
  /// leading `..` segments;
  /// a path that starts with `/` will also drop any leading `..` segments.
  ///
  /// This uses the same normalization strategy as `Uri().resolve(this)`.
  ///
  /// Does not change any part of the URI except the path.
  ///
  /// The default implementation of `Uri` always normalizes paths, so calling
  /// this function has no effect.
  Uri normalizePath();

  /// Creates a new `Uri` object by parsing a URI string.
  ///
  /// If [start] and [end] are provided, they must specify a valid substring
  /// of [uri], and only the substring from `start` to `end` is parsed as a URI.
  ///
  /// If the [uri] string is not valid as a URI or URI reference,
  /// a [FormatException] is thrown.
  ///
  /// Example:
  /// ```dart
  /// final uri =
  ///     Uri.parse('https://example.com/api/fetch?limit=10,20,30&max=100');
  /// print(uri); // https://example.com/api/fetch?limit=10,20,30&max=100
  ///
  /// Uri.parse('::Not valid URI::'); // Throws FormatException.
  /// ```
  static Uri parse(String uri, [int start = 0, int? end]) {
    // This parsing will not validate percent-encoding, IPv6, etc.
    // When done splitting into parts, it will call, e.g., [_makeFragment]
    // to do the final parsing.
    //
    // Important parts of the RFC 3986 used here:
    // URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
    //
    // hier-part     = "//" authority path-abempty
    //               / path-absolute
    //               / path-rootless
    //               / path-empty
    //
    // URI-reference = URI / relative-ref
    //
    // absolute-URI  = scheme ":" hier-part [ "?" query ]
    //
    // relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
    //
    // relative-part = "//" authority path-abempty
    //               / path-absolute
    //               / path-noscheme
    //               / path-empty
    //
    // scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
    //
    // authority     = [ userinfo "@" ] host [ ":" port ]
    // userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
    // host          = IP-literal / IPv4address / reg-name
    // IP-literal    = "[" ( IPv6address / IPv6addrz / IPvFuture ) "]"
    // IPv6addrz     = IPv6address "%25" ZoneID
    // ZoneID        = 1*( unreserved / pct-encoded )
    // port          = *DIGIT
    // reg-name      = *( unreserved / pct-encoded / sub-delims )
    //
    // path          = path-abempty    ; begins with "/" or is empty
    //               / path-absolute   ; begins with "/" but not "//"
    //               / path-noscheme   ; begins with a non-colon segment
    //               / path-rootless   ; begins with a segment
    //               / path-empty      ; zero characters
    //
    // path-abempty  = *( "/" segment )
    // path-absolute = "/" [ segment-nz *( "/" segment ) ]
    // path-noscheme = segment-nz-nc *( "/" segment )
    // path-rootless = segment-nz *( "/" segment )
    // path-empty    = 0<pchar>
    //
    // segment       = *pchar
    // segment-nz    = 1*pchar
    // segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
    //               ; non-zero-length segment without any colon ":"
    //
    // pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
    //
    // query         = *( pchar / "/" / "?" )
    //
    // fragment      = *( pchar / "/" / "?" )
    end ??= uri.length;

    // Special case data:URIs. Ignore case when testing.
    if (end >= start + 5) {
      int dataDelta = _startsWithData(uri, start);
      if (dataDelta == 0) {
        // The case is right.
        if (start > 0 || end < uri.length) uri = uri.substring(start, end);
        return UriData._parse(uri, 5, null).uri;
      } else if (dataDelta == 0x20) {
        return UriData._parse(uri.substring(start + 5, end), 0, null).uri;
      }
      // Otherwise the URI doesn't start with "data:" or any case variant of it.
    }

    // The following index-normalization belongs with the scanning, but is
    // easier to do here because we already have extracted variables from the
    // indices list.
    var indices = List<int>.filled(8, 0, growable: false);

    // Set default values for each position.
    // The value will either be correct in some cases where it isn't set
    // by the scanner, or it is clearly recognizable as an unset value.
    indices
      ..[0] = 0
      ..[_schemeEndIndex] = start - 1
      ..[_hostStartIndex] = start - 1
      ..[_notSimpleIndex] = start - 1
      ..[_portStartIndex] = start
      ..[_pathStartIndex] = start
      ..[_queryStartIndex] = end
      ..[_fragmentStartIndex] = end;
    var state = _scan(uri, start, end, _uriStart, indices);
    // Some states that should be non-simple, but the URI ended early.
    // Paths that end at a ".." must be normalized to end in "../".
    if (state >= _nonSimpleEndStates) {
      indices[_notSimpleIndex] = end;
    }
    int schemeEnd = indices[_schemeEndIndex];
    if (schemeEnd >= start) {
      // Rescan the scheme part now that we know it's not a path.
      state = _scan(uri, start, schemeEnd, _schemeStart, indices);
      if (state == _schemeStart) {
        // Empty scheme.
        indices[_notSimpleIndex] = schemeEnd;
      }
    }
    // The returned positions are limited by the scanners ability to write only
    // one position per character, and only the current position.
    // Scanning from left to right, we only know whether something is a scheme
    // or a path when we see a `:` or `/`, and likewise we only know if the first
    // `/` is part of the path or is leading an authority component when we see
    // the next character.

    int hostStart = indices[_hostStartIndex] + 1;
    int portStart = indices[_portStartIndex];
    int pathStart = indices[_pathStartIndex];
    int queryStart = indices[_queryStartIndex];
    int fragmentStart = indices[_fragmentStartIndex];

    // We may discover the scheme while handling special cases.
    String? scheme;

    // Derive some positions that weren't set to normalize the indices.
    if (fragmentStart < queryStart) queryStart = fragmentStart;
    // If pathStart isn't set (it's before scheme end or host start), then
    // the path is empty, or there is no authority part and the path
    // starts with a non-simple character.
    if (pathStart < hostStart) {
      // There is an authority, but no path. The path would start with `/`
      // if it was there.
      pathStart = queryStart;
    } else if (pathStart <= schemeEnd) {
      // There is a scheme, but no authority.
      pathStart = schemeEnd + 1;
    }
    // If there is an authority with no port, set the port position
    // to be at the end of the authority (equal to pathStart).
    // This also handles a ":" in a user-info component incorrectly setting
    // the port start position.
    if (portStart < hostStart) portStart = pathStart;

    assert(hostStart == start || schemeEnd <= hostStart);
    assert(hostStart <= portStart);
    assert(schemeEnd <= pathStart);
    assert(portStart <= pathStart);
    assert(pathStart <= queryStart);
    assert(queryStart <= fragmentStart);

    bool isSimple = indices[_notSimpleIndex] < start;

    if (isSimple) {
      // Check/do normalizations that weren't detected by the scanner.
      // This includes removal of empty port or userInfo,
      // or scheme specific port and path normalizations.
      if (hostStart > schemeEnd + 3) {
        // Always be non-simple if URI contains user-info.
        // The scanner doesn't set the not-simple position in this case because
        // it's setting the host-start position instead.
        isSimple = false;
      } else if (portStart > start && portStart + 1 == pathStart) {
        // If the port is empty, it should be omitted.
        // Pathological case, don't bother correcting it.
        isSimple = false;
      } else if (uri.startsWith(r"\", pathStart) ||
          hostStart > start &&
              (uri.startsWith(r"\", hostStart - 1) ||
                  uri.startsWith(r"\", hostStart - 2))) {
        // Seeing a `\` anywhere.
        // The scanner doesn't record when the first path character is a `\`
        // or when the last slash before the authority is a `\`.
        isSimple = false;
      } else if (queryStart < end &&
              (queryStart == pathStart + 2 &&
                  uri.startsWith("..", pathStart)) ||
          (queryStart > pathStart + 2 &&
              uri.startsWith("/..", queryStart - 3))) {
        // The path ends in a ".." segment. This should be normalized to "../".
        // We didn't detect this while scanning because a query or fragment was
        // detected at the same time (which is why we only need to check this
        // if there is something after the path).
        isSimple = false;
      } else {
        // There are a few scheme-based normalizations that
        // the scanner couldn't check.
        // That means that the input is very close to simple, so just do
        // the normalizations.
        if (schemeEnd == start + 4) {
          // Do scheme based normalizations for file, http.
          if (uri.startsWith("file", start)) {
            scheme = "file";
            if (hostStart <= start) {
              // File URIs should have an authority.
              // Paths after an authority should be absolute.
              String schemeAuth = "file://";
              int delta = 2;
              if (!uri.startsWith("/", pathStart)) {
                schemeAuth = "file:///";
                delta = 3;
              }
              uri = schemeAuth + uri.substring(pathStart, end);
              schemeEnd -= start;
              hostStart = 7;
              portStart = 7;
              pathStart = 7;
              queryStart += delta - start;
              fragmentStart += delta - start;
              start = 0;
              end = uri.length;
            } else if (pathStart == queryStart) {
              // Uri has authority and empty path. Add "/" as path.
              if (start == 0 && end == uri.length) {
                uri = uri.replaceRange(pathStart, queryStart, "/");
                queryStart += 1;
                fragmentStart += 1;
                end += 1;
              } else {
                uri =
                    "${uri.substring(start, pathStart)}/"
                    "${uri.substring(queryStart, end)}";
                schemeEnd -= start;
                hostStart -= start;
                portStart -= start;
                pathStart -= start;
                queryStart += 1 - start;
                fragmentStart += 1 - start;
                start = 0;
                end = uri.length;
              }
            }
          } else if (uri.startsWith("http", start)) {
            scheme = "http";
            // HTTP URIs should not have an explicit port of 80.
            if (portStart > start &&
                portStart + 3 == pathStart &&
                uri.startsWith("80", portStart + 1)) {
              if (start == 0 && end == uri.length) {
                uri = uri.replaceRange(portStart, pathStart, "");
                pathStart -= 3;
                queryStart -= 3;
                fragmentStart -= 3;
                end -= 3;
              } else {
                uri =
                    uri.substring(start, portStart) +
                    uri.substring(pathStart, end);
                schemeEnd -= start;
                hostStart -= start;
                portStart -= start;
                pathStart -= 3 + start;
                queryStart -= 3 + start;
                fragmentStart -= 3 + start;
                start = 0;
                end = uri.length;
              }
            }
          }
        } else if (schemeEnd == start + 5 && uri.startsWith("https", start)) {
          scheme = "https";
          // HTTPS URIs should not have an explicit port of 443.
          if (portStart > start &&
              portStart + 4 == pathStart &&
              uri.startsWith("443", portStart + 1)) {
            if (start == 0 && end == uri.length) {
              uri = uri.replaceRange(portStart, pathStart, "");
              pathStart -= 4;
              queryStart -= 4;
              fragmentStart -= 4;
              end -= 3;
            } else {
              uri =
                  uri.substring(start, portStart) +
                  uri.substring(pathStart, end);
              schemeEnd -= start;
              hostStart -= start;
              portStart -= start;
              pathStart -= 4 + start;
              queryStart -= 4 + start;
              fragmentStart -= 4 + start;
              start = 0;
              end = uri.length;
            }
          }
        }
      }
    }

    if (isSimple) {
      if (start > 0 || end < uri.length) {
        uri = uri.substring(start, end);
        schemeEnd -= start;
        hostStart -= start;
        portStart -= start;
        pathStart -= start;
        queryStart -= start;
        fragmentStart -= start;
      }
      return _SimpleUri(
        uri,
        schemeEnd,
        hostStart,
        portStart,
        pathStart,
        queryStart,
        fragmentStart,
        scheme,
      );
    }

    return _Uri.notSimple(
      uri,
      start,
      end,
      schemeEnd,
      hostStart,
      portStart,
      pathStart,
      queryStart,
      fragmentStart,
      scheme,
    );
  }

  /// Creates a new `Uri` object by parsing a URI string.
  ///
  /// If [start] and [end] are provided, they must specify a valid substring
  /// of [uri], and only the substring from `start` to `end` is parsed as a URI.
  ///
  /// Returns `null` if the [uri] string is not valid as a URI or URI reference.
  ///
  /// Example:
  /// ```dart
  /// final uri = Uri.tryParse(
  ///     'https://dart.dev/guides/libraries/library-tour#utility-classes', 0,
  ///     16);
  /// print(uri); // https://dart.dev
  ///
  /// var notUri = Uri.tryParse('::Not valid URI::');
  /// print(notUri); // null
  /// ```
  static Uri? tryParse(String uri, [int start = 0, int? end]) {
    // TODO: Optimize to avoid throwing-and-recatching.
    try {
      return parse(uri, start, end);
    } on FormatException {
      return null;
    }
  }

  /// Encode the string [component] using percent-encoding to make it
  /// safe for literal use as a URI component.
  ///
  /// All characters except uppercase and lowercase letters, digits and
  /// the characters `-_.!~*'()` are percent-encoded. This is the
  /// set of characters specified in RFC 2396 and which is
  /// specified for the encodeUriComponent in ECMA-262 version 5.1.
  ///
  /// When manually encoding path segments or query components, remember
  /// to encode each part separately before building the path or query
  /// string.
  ///
  /// For encoding the query part consider using
  /// [encodeQueryComponent].
  ///
  /// To avoid the need for explicitly encoding, use the [pathSegments]
  /// and [queryParameters] optional named arguments when constructing
  /// a [Uri].
  ///
  /// Example:
  /// ```dart
  /// const request = 'http://example.com/search=Dart';
  /// final encoded = Uri.encodeComponent(request);
  /// print(encoded); // http%3A%2F%2Fexample.com%2Fsearch%3DDart
  /// ```
  static String encodeComponent(String component) {
    return _Uri._uriEncode(_unreserved2396Mask, component, utf8, false);
  }

  /**
   * Encodes the string [component] according to the HTML 4.01 rules
   * for encoding the posting of a HTML form as a query string
   * component.

   * The component is first encoded to bytes using [encoding].
   * The default is to use [utf8] encoding, which preserves all
   * the characters that don't need encoding.

   * Then the resulting bytes are "percent-encoded". This transforms
   * spaces (U+0020) to a plus sign ('+') and all bytes that are not
   * the ASCII decimal digits, letters or one of '-._~' are written as
   * a percent sign '%' followed by the two-digit hexadecimal
   * representation of the byte.

   * Note that the set of characters which are percent-encoded is a
   * superset of what HTML 4.01 requires, since it refers to RFC 1738
   * for reserved characters.
   *
   * When manually encoding query components remember to encode each
   * part separately before building the query string.
   *
   * To avoid the need for explicitly encoding the query use the
   * [queryParameters] optional named arguments when constructing a
   * [Uri].
   *
   * See https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 for more
   * details.
   */
  static String encodeQueryComponent(
    String component, {
    Encoding encoding = utf8,
  }) {
    return _Uri._uriEncode(_unreservedMask, component, encoding, true);
  }

  /// Decodes the percent-encoding in [encodedComponent].
  ///
  /// Note that decoding a URI component might change its meaning as
  /// some of the decoded characters could be characters which are
  /// delimiters for a given URI component type. Always split a URI
  /// component using the delimiters for the component before decoding
  /// the individual parts.
  ///
  /// For handling the [path] and [query] components, consider using
  /// [pathSegments] and [queryParameters] to get the separated and
  /// decoded component.
  ///
  /// Example:
  /// ```dart
  /// final decoded =
  ///     Uri.decodeComponent('http%3A%2F%2Fexample.com%2Fsearch%3DDart');
  /// print(decoded); // http://example.com/search=Dart
  /// ```
  static String decodeComponent(String encodedComponent) {
    return _Uri._uriDecode(
      encodedComponent,
      0,
      encodedComponent.length,
      utf8,
      false,
    );
  }

  /// Decodes the percent-encoding in [encodedComponent], converting
  /// pluses to spaces.
  ///
  /// It will create a byte-list of the decoded characters, and then use
  /// [encoding] to decode the byte-list to a String. The default encoding is
  /// UTF-8.
  static String decodeQueryComponent(
    String encodedComponent, {
    Encoding encoding = utf8,
  }) {
    return _Uri._uriDecode(
      encodedComponent,
      0,
      encodedComponent.length,
      encoding,
      true,
    );
  }

  /// Encodes the string [uri] using percent-encoding to make it
  /// safe for literal use as a full URI.
  ///
  /// All characters except uppercase and lowercase letters, digits and
  /// the characters `!#$&'()*+,-./:;=?@_~` are percent-encoded. This
  /// is the set of characters specified in ECMA-262 version 5.1 for
  /// the encodeURI function.
  ///
  /// Example:
  /// ```dart
  /// final encoded =
  ///     Uri.encodeFull('https://example.com/api/query?search= dart is');
  /// print(encoded); // https://example.com/api/query?search=%20dart%20is
  /// ```
  static String encodeFull(String uri) {
    return _Uri._uriEncode(_encodeFullMask, uri, utf8, false);
  }

  /// Decodes the percent-encoding in [uri].
  ///
  /// Note that decoding a full URI might change its meaning as some of
  /// the decoded characters could be reserved characters. In most
  /// cases, an encoded URI should be parsed into components using
  /// [Uri.parse] before decoding the separate components.
  ///
  /// Example:
  /// ```dart
  /// final decoded =
  ///     Uri.decodeFull('https://example.com/api/query?search=%20dart%20is');
  /// print(decoded); // https://example.com/api/query?search= dart is
  /// ```
  static String decodeFull(String uri) {
    return _Uri._uriDecode(uri, 0, uri.length, utf8, false);
  }

  /// Splits the [query] into a map according to the rules
  /// specified for FORM post in the [HTML 4.01 specification section
  /// 17.13.4](https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4
  /// "HTML 4.01 section 17.13.4").
  ///
  /// Each key and value in the returned map has been decoded. If the [query]
  /// is the empty string, an empty map is returned.
  ///
  /// Keys in the query string that have no value are mapped to the
  /// empty string.
  ///
  /// Each query component will be decoded using [encoding]. The default
  /// encoding is UTF-8.
  ///
  /// Example:
  /// ```dart import:convert
  /// final queryStringMap =
  ///     Uri.splitQueryString('limit=10&max=100&search=Dart%20is%20fun');
  /// print(jsonEncode(queryStringMap));
  /// // {"limit":"10","max":"100","search":"Dart is fun"}
  ///
  /// ```
  static Map<String, String> splitQueryString(
    String query, {
    Encoding encoding = utf8,
  }) {
    return query.split("&").fold({}, (map, element) {
      int index = element.indexOf("=");
      if (index == -1) {
        if (element != "") {
          map[decodeQueryComponent(element, encoding: encoding)] = "";
        }
      } else if (index != 0) {
        var key = element.substring(0, index);
        var value = element.substring(index + 1);
        map[decodeQueryComponent(
          key,
          encoding: encoding,
        )] = decodeQueryComponent(value, encoding: encoding);
      }
      return map;
    });
  }

  /// Parses the [host] as an IP version 4 (IPv4) address, returning the address
  /// as a list of 4 bytes in network byte order (big endian).
  ///
  /// Throws a [FormatException] if [host] is not a valid IPv4 address
  /// representation.
  static List<int> parseIPv4Address(String host) =>
      _parseIPv4Address(host, 0, host.length);

  /// Implementation of [parseIPv4Address] that can work on a substring.
  static List<int> _parseIPv4Address(String host, int start, int end) {
    void error(String msg, int position) {
      throw FormatException('Illegal IPv4 address, $msg', host, position);
    }

    var result = Uint8List(4);
    int partIndex = 0;
    int partStart = start;
    for (int i = start; i < end; i++) {
      int char = host.codeUnitAt(i);
      if (char != _DOT) {
        if (char ^ 0x30 > 9) {
          // Fail on a non-digit character.
          error("invalid character", i);
        }
      } else {
        if (partIndex == 3) {
          error('IPv4 address should contain exactly 4 parts', i);
        }
        int part = int.parse(host.substring(partStart, i));
        if (part > 255) {
          error("each part must be in the range 0..255", partStart);
        }
        result[partIndex++] = part;
        partStart = i + 1;
      }
    }

    if (partIndex != 3) {
      error('IPv4 address should contain exactly 4 parts', end);
    }

    int part = int.parse(host.substring(partStart, end));
    if (part > 255) {
      error("each part must be in the range 0..255", partStart);
    }
    result[partIndex] = part;

    return result;
  }

  /// Parses the [host] as an IP version 6 (IPv6) address.
  ///
  /// Returns the address as a list of 16 bytes in network byte order
  /// (big endian).
  ///
  /// Throws a [FormatException] if [host] is not a valid IPv6 address
  /// representation.
  ///
  /// Acts on the substring from [start] to [end]. If [end] is omitted, it
  /// defaults to the end of the string.
  ///
  /// Some examples of IPv6 addresses:
  ///  * `::1`
  ///  * `FEDC:BA98:7654:3210:FEDC:BA98:7654:3210`
  ///  * `3ffe:2a00:100:7031::1`
  ///  * `::FFFF:129.144.52.38`
  ///  * `2010:836B:4179::836B:4179`
  static List<int> parseIPv6Address(String host, [int start = 0, int? end]) {
    end ??= host.length;
    // An IPv6 address consists of exactly 8 parts of 1-4 hex digits, separated
    // by `:`'s, with the following exceptions:
    //
    //  - One (and only one) wildcard (`::`) may be present, representing a fill
    //    of 0's. The IPv6 `::` is thus 16 bytes of `0`.
    //  - The last two parts may be replaced by an IPv4 "dotted-quad" address.

    // Helper function for reporting a badly formatted IPv6 address.
    void error(String msg, int? position) {
      throw FormatException('Illegal IPv6 address, $msg', host, position);
    }

    // Parse a hex block.
    int parseHex(int start, int end) {
      if (end - start > 4) {
        error('an IPv6 part can only contain a maximum of 4 hex digits', start);
      }
      int value = int.parse(host.substring(start, end), radix: 16);
      if (value < 0 || value > 0xFFFF) {
        error('each part must be in the range of `0x0..0xFFFF`', start);
      }
      return value;
    }

    if (host.length < 2) error('address is too short', null);
    List<int> parts = [];
    bool wildcardSeen = false;
    // Set if seeing a ".", suggesting that there is an IPv4 address.
    bool seenDot = false;
    int partStart = start;
    // Parse all parts, except a potential last one.
    for (int i = start; i < end; i++) {
      int char = host.codeUnitAt(i);
      if (char == _COLON) {
        if (i == start) {
          // If we see a `:` in the beginning, expect wildcard.
          i++;
          if (host.codeUnitAt(i) != _COLON) {
            error('invalid start colon.', i);
          }
          partStart = i;
        }
        if (i == partStart) {
          // Wildcard. We only allow one.
          if (wildcardSeen) {
            error('only one wildcard `::` is allowed', i);
          }
          wildcardSeen = true;
          parts.add(-1);
        } else {
          // Found a single colon. Parse [partStart..i] as a hex entry.
          parts.add(parseHex(partStart, i));
        }
        partStart = i + 1;
      } else if (char == _DOT) {
        seenDot = true;
      }
    }
    if (parts.length == 0) error('too few parts', null);
    bool atEnd = (partStart == end);
    bool isLastWildcard = (parts.last == -1);
    if (atEnd && !isLastWildcard) {
      error('expected a part after last `:`', end);
    }
    if (!atEnd) {
      if (!seenDot) {
        parts.add(parseHex(partStart, end));
      } else {
        List<int> last = _parseIPv4Address(host, partStart, end);
        parts.add(last[0] << 8 | last[1]);
        parts.add(last[2] << 8 | last[3]);
      }
    }
    if (wildcardSeen) {
      if (parts.length > 7) {
        error('an address with a wildcard must have less than 7 parts', null);
      }
    } else if (parts.length != 8) {
      error('an address without a wildcard must contain exactly 8 parts', null);
    }
    List<int> bytes = Uint8List(16);
    for (int i = 0, index = 0; i < parts.length; i++) {
      int value = parts[i];
      if (value == -1) {
        int wildCardLength = 9 - parts.length;
        for (int j = 0; j < wildCardLength; j++) {
          bytes[index] = 0;
          bytes[index + 1] = 0;
          index += 2;
        }
      } else {
        bytes[index] = value >> 8;
        bytes[index + 1] = value & 0xff;
        index += 2;
      }
    }
    return bytes;
  }
}

// Superclass of the two implementation types.
sealed class _PlatformUri implements Uri {}

final class _Uri implements _PlatformUri {
  // We represent the missing scheme as an empty string.
  // A valid scheme cannot be empty.
  final String scheme;

  /// The user-info part of the authority.
  ///
  /// Does not distinguish between an empty user-info and an absent one.
  /// The value is always non-null.
  /// Is considered absent if [_host] is `null`.
  final String _userInfo;

  /// The host name of the URI.
  ///
  /// Set to `null` if there is no authority in the URI.
  /// The host name is the only mandatory part of an authority, so we use
  /// it to mark whether an authority part was present or not.
  final String? _host;

  /// The port number part of the authority.
  ///
  /// The port. Set to null if there is no port. Normalized to null if
  /// the port is the default port for the scheme.
  int? _port;

  /// The path of the URI.
  ///
  /// Always non-null.
  final String path;

  /// The query content, or null if there is no query.
  final String? _query;

  // The fragment content, or null if there is no fragment.
  final String? _fragment;

  /// Cache of the full normalized text representation of the URI.
  late final String _text = this._initializeText();

  /// Cache of the list of path segments.
  late final List<String> pathSegments = _computePathSegments(this.path);

  /// Lazily computed and cached hashCode of [_text].
  late final int hashCode = this._text.hashCode;

  /// Cache the computed return value of [queryParameters].
  late final Map<String, String> queryParameters =
      UnmodifiableMapView<String, String>(Uri.splitQueryString(this.query));

  /// Cache the computed return value of [queryParametersAll].
  late final Map<String, List<String>> queryParametersAll =
      _computeQueryParametersAll(this.query);

  /// Internal non-verifying constructor. Only call with validated arguments.
  ///
  /// The components must be properly normalized.
  ///
  /// Use `null` for [_host] if there is no authority. In that case, always
  /// pass `null` for [_port] and an empty string for [_userInfo] as well.
  ///
  /// Use `null` for [_port], [_query] and [_fragment] if there is
  /// component of that type, and empty string for [_userInfo].
  ///
  /// The [path] and [scheme] are never empty.
  _Uri._internal(
    this.scheme,
    this._userInfo,
    this._host,
    this._port,
    this.path,
    this._query,
    this._fragment,
  );

  /// Create a [_Uri] from parts of [uri].
  ///
  /// The parameters specify the start/end of particular components of the URI.
  /// The [scheme] may contain a string representing a normalized scheme
  /// component if one has already been discovered.
  factory _Uri.notSimple(
    String uri,
    int start,
    int end,
    int schemeEnd,
    int hostStart,
    int portStart,
    int pathStart,
    int queryStart,
    int fragmentStart,
    String? scheme,
  ) {
    if (scheme == null) {
      scheme = "";
      if (schemeEnd > start) {
        scheme = _makeScheme(uri, start, schemeEnd);
      } else if (schemeEnd == start) {
        _fail(uri, start, "Invalid empty scheme");
      }
    }
    String userInfo = "";
    String? host;
    int? port;
    if (hostStart > start) {
      int userInfoStart = schemeEnd + 3;
      if (userInfoStart < hostStart) {
        userInfo = _makeUserInfo(uri, userInfoStart, hostStart - 1);
      }
      host = _makeHost(uri, hostStart, portStart, false);
      if (portStart + 1 < pathStart) {
        int portNumber =
            int.tryParse(uri.substring(portStart + 1, pathStart)) ??
            (throw FormatException("Invalid port", uri, portStart + 1));
        port = _makePort(portNumber, scheme);
      }
    }
    String path = _makePath(
      uri,
      pathStart,
      queryStart,
      null,
      scheme,
      host != null,
    );
    String? query;
    if (queryStart < fragmentStart) {
      query = _makeQuery(uri, queryStart + 1, fragmentStart, null);
    }
    String? fragment;
    if (fragmentStart < end) {
      fragment = _makeFragment(uri, fragmentStart + 1, end);
    }
    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
  }

  /// Implementation of [Uri.Uri].
  factory _Uri({
    String? scheme,
    String? userInfo,
    String? host,
    int? port,
    String? path,
    Iterable<String>? pathSegments,
    String? query,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
    String? fragment,
  }) {
    if (scheme == null) {
      scheme = "";
    } else {
      scheme = _makeScheme(scheme, 0, scheme.length);
    }
    userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
    if (userInfo == null) {
      // TODO(dart-lang/language#440): Remove when promotion works.
      throw "unreachable";
    }
    host = _makeHost(host, 0, _stringOrNullLength(host), false);
    // Special case this constructor for backwards compatibility.
    if (query == "") query = null;
    query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
    fragment = _makeFragment(fragment, 0, _stringOrNullLength(fragment));
    port = _makePort(port, scheme);
    bool isFile = (scheme == "file");
    if (host == null && (userInfo.isNotEmpty || port != null || isFile)) {
      host = "";
    }
    bool hasAuthority = (host != null);
    path = _makePath(
      path,
      0,
      _stringOrNullLength(path),
      pathSegments,
      scheme,
      hasAuthority,
    );
    if (path == null) {
      // TODO(dart-lang/language#440): Remove when promotion works.
      throw "unreachable";
    }
    if (scheme.isEmpty && host == null && !path.startsWith('/')) {
      bool allowScheme = scheme.isNotEmpty || host != null;
      path = _normalizeRelativePath(path, allowScheme);
    } else {
      path = _removeDotSegments(path);
    }
    if (host == null && path.startsWith("//")) {
      host = "";
    }
    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
  }

  /// Implementation of [Uri.http].
  factory _Uri.http(
    String authority, [
    String unencodedPath = '',
    Map<String, dynamic>? queryParameters,
  ]) {
    return _makeHttpUri("http", authority, unencodedPath, queryParameters);
  }

  /// Implementation of [Uri.https].
  factory _Uri.https(
    String authority, [
    String unencodedPath = '',
    Map<String, dynamic>? queryParameters,
  ]) {
    return _makeHttpUri("https", authority, unencodedPath, queryParameters);
  }

  String get authority {
    if (!hasAuthority) return "";
    var sb = StringBuffer();
    _writeAuthority(sb);
    return sb.toString();
  }

  String get userInfo => _userInfo;

  String get host {
    String? host = _host;
    if (host == null) return "";
    if (host.startsWith('[')) {
      return host.substring(1, host.length - 1);
    }
    return host;
  }

  int get port {
    return _port ?? _defaultPort(scheme);
  }

  /// The default port for the scheme of this Uri.
  static int _defaultPort(String scheme) {
    if (scheme == "http") return 80;
    if (scheme == "https") return 443;
    return 0;
  }

  String get query => _query ?? "";

  String get fragment => _fragment ?? "";

  bool isScheme(String scheme) {
    String thisScheme = this.scheme;
    if (scheme == null) return thisScheme.isEmpty;
    if (scheme.length != thisScheme.length) return false;
    return _caseInsensitiveStartsWith(scheme, thisScheme, 0);
  }

  /// Report a parse failure.
  static Never _fail(String uri, int index, String message) {
    throw FormatException(message, uri, index);
  }

  static _Uri _makeHttpUri(
    String scheme,
    String? authority,
    String unencodedPath,
    Map<String, dynamic>? queryParameters,
  ) {
    var userInfo = "";
    String? host;
    int? port;

    if (authority != null && authority.isNotEmpty) {
      var hostStart = 0;
      // Split off the user info.
      for (int i = 0; i < authority.length; i++) {
        const int atSign = 0x40;
        if (authority.codeUnitAt(i) == atSign) {
          userInfo = authority.substring(0, i);
          hostStart = i + 1;
          break;
        }
      }
      var hostEnd = hostStart;
      if (hostStart < authority.length &&
          authority.codeUnitAt(hostStart) == _LEFT_BRACKET) {
        // IPv6 host.
        int escapeForZoneID = -1;
        for (; hostEnd < authority.length; hostEnd++) {
          int char = authority.codeUnitAt(hostEnd);
          if (char == _PERCENT && escapeForZoneID < 0) {
            escapeForZoneID = hostEnd;
            if (authority.startsWith("25", hostEnd + 1)) {
              hostEnd += 2; // Might as well skip the already checked escape.
            }
          } else if (char == _RIGHT_BRACKET) {
            break;
          }
        }
        if (hostEnd == authority.length) {
          throw FormatException(
            "Invalid IPv6 host entry.",
            authority,
            hostStart,
          );
        }
        Uri.parseIPv6Address(
          authority,
          hostStart + 1,
          (escapeForZoneID < 0) ? hostEnd : escapeForZoneID,
        );
        hostEnd++; // Skip the closing bracket.
        if (hostEnd != authority.length &&
            authority.codeUnitAt(hostEnd) != _COLON) {
          throw FormatException("Invalid end of authority", authority, hostEnd);
        }
      }
      // Split host and port.
      for (; hostEnd < authority.length; hostEnd++) {
        if (authority.codeUnitAt(hostEnd) == _COLON) {
          var portString = authority.substring(hostEnd + 1);
          // We allow the empty port - falling back to initial value.
          if (portString.isNotEmpty) port = int.parse(portString);
          break;
        }
      }
      host = authority.substring(hostStart, hostEnd);
    }
    return _Uri(
      scheme: scheme,
      userInfo: userInfo,
      host: host,
      port: port,
      pathSegments: unencodedPath.split("/"),
      queryParameters: queryParameters,
    );
  }

  /// Implementation of [Uri.file].
  factory _Uri.file(String path, {bool? windows}) {
    return (windows ?? _Uri._isWindows)
        ? _makeWindowsFileUrl(path, false)
        : _makeFileUri(path, false);
  }

  /// Implementation of [Uri.directory].
  factory _Uri.directory(String path, {bool? windows}) {
    return (windows ?? _Uri._isWindows)
        ? _makeWindowsFileUrl(path, true)
        : _makeFileUri(path, true);
  }

  /// Used internally in path-related constructors.
  external static bool get _isWindows;

  static void _checkNonWindowsPathReservedCharacters(
    List<String> segments,
    bool argumentError,
  ) {
    for (var segment in segments) {
      if (segment.contains("/")) {
        if (argumentError) {
          throw ArgumentError("Illegal path character $segment");
        } else {
          throw UnsupportedError("Illegal path character $segment");
        }
      }
    }
  }

  static void _checkWindowsPathReservedCharacters(
    List<String> segments,
    bool argumentError, [
    int firstSegment = 0,
  ]) {
    for (var segment in segments.skip(firstSegment)) {
      if (segment.contains(RegExp(r'["*/:<>?\\|]'))) {
        if (argumentError) {
          throw ArgumentError("Illegal character in path");
        } else {
          throw UnsupportedError("Illegal character in path: $segment");
        }
      }
    }
  }

  static void _checkWindowsDriveLetter(int charCode, bool argumentError) {
    if ((_UPPER_CASE_A <= charCode && charCode <= _UPPER_CASE_Z) ||
        (_LOWER_CASE_A <= charCode && charCode <= _LOWER_CASE_Z)) {
      return;
    }
    if (argumentError) {
      throw ArgumentError(
        "Illegal drive letter " + String.fromCharCode(charCode),
      );
    } else {
      throw UnsupportedError(
        "Illegal drive letter " + String.fromCharCode(charCode),
      );
    }
  }

  static Uri _makeFileUri(String path, bool slashTerminated) {
    const String sep = "/";
    var segments = path.split(sep);
    if (slashTerminated && segments.isNotEmpty && segments.last.isNotEmpty) {
      segments.add(""); // Extra separator at end.
    }
    if (path.startsWith(sep)) {
      // Absolute file:// URI.
      return Uri(scheme: "file", pathSegments: segments);
    } else {
      // Relative URI.
      return Uri(pathSegments: segments);
    }
  }

  static _makeWindowsFileUrl(String path, bool slashTerminated) {
    if (path.startsWith(r"\\?\")) {
      if (path.startsWith(r"UNC\", 4)) {
        path = path.replaceRange(0, 7, r'\');
      } else {
        path = path.substring(4);
        if (path.length < 3 ||
            path.codeUnitAt(1) != _COLON ||
            path.codeUnitAt(2) != _BACKSLASH) {
          throw ArgumentError.value(
            path,
            "path",
            r"Windows paths with \\?\ prefix must be absolute",
          );
        }
      }
    } else {
      path = path.replaceAll("/", r'\');
    }
    const String sep = r'\';
    if (path.length > 1 && path.codeUnitAt(1) == _COLON) {
      _checkWindowsDriveLetter(path.codeUnitAt(0), true);
      if (path.length == 2 || path.codeUnitAt(2) != _BACKSLASH) {
        throw ArgumentError.value(
          path,
          "path",
          "Windows paths with drive letter must be absolute",
        );
      }
      // Absolute file://C:/ URI.
      var pathSegments = path.split(sep);
      if (slashTerminated && pathSegments.last.isNotEmpty) {
        pathSegments.add(""); // Extra separator at end.
      }
      _checkWindowsPathReservedCharacters(pathSegments, true, 1);
      return Uri(scheme: "file", pathSegments: pathSegments);
    }

    if (path.startsWith(sep)) {
      if (path.startsWith(sep, 1)) {
        // Absolute file:// URI with host.
        int pathStart = path.indexOf(r'\', 2);
        String hostPart =
            (pathStart < 0) ? path.substring(2) : path.substring(2, pathStart);
        String pathPart = (pathStart < 0) ? "" : path.substring(pathStart + 1);
        var pathSegments = pathPart.split(sep);
        _checkWindowsPathReservedCharacters(pathSegments, true);
        if (slashTerminated && pathSegments.last.isNotEmpty) {
          pathSegments.add(""); // Extra separator at end.
        }
        return Uri(scheme: "file", host: hostPart, pathSegments: pathSegments);
      } else {
        // Absolute file:// URI.
        var pathSegments = path.split(sep);
        if (slashTerminated && pathSegments.last.isNotEmpty) {
          pathSegments.add(""); // Extra separator at end.
        }
        _checkWindowsPathReservedCharacters(pathSegments, true);
        return Uri(scheme: "file", pathSegments: pathSegments);
      }
    } else {
      // Relative URI.
      var pathSegments = path.split(sep);
      _checkWindowsPathReservedCharacters(pathSegments, true);
      if (slashTerminated &&
          pathSegments.isNotEmpty &&
          pathSegments.last.isNotEmpty) {
        pathSegments.add(""); // Extra separator at end.
      }
      return Uri(pathSegments: pathSegments);
    }
  }

  Uri replace({
    String? scheme,
    String? userInfo,
    String? host,
    int? port,
    String? path,
    Iterable<String>? pathSegments,
    String? query,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
    String? fragment,
  }) {
    // Set to true if the scheme has (potentially) changed.
    // In that case, the default port may also have changed and we need
    // to check even the existing port.
    bool schemeChanged = false;
    if (scheme != null) {
      scheme = _makeScheme(scheme, 0, scheme.length);
      schemeChanged = (scheme != this.scheme);
    } else {
      scheme = this.scheme;
    }

    bool isFile = (scheme == "file");
    if (userInfo != null) {
      userInfo = _makeUserInfo(userInfo, 0, userInfo.length);
    } else {
      userInfo = this._userInfo;
    }

    if (port != null) {
      port = _makePort(port, scheme);
    } else {
      port = this._port;
      if (schemeChanged) {
        // The default port might have changed.
        port = _makePort(port, scheme);
      }
    }
    if (host != null) {
      host = _makeHost(host, 0, host.length, false);
    } else if (this.hasAuthority) {
      host = this._host;
    } else if (userInfo.isNotEmpty || port != null || isFile) {
      host = "";
    }

    bool hasAuthority = host != null;
    if (path != null || pathSegments != null) {
      path = _makePath(
        path,
        0,
        _stringOrNullLength(path),
        pathSegments,
        scheme,
        hasAuthority,
      );
    } else {
      var currentPath = this.path;
      if ((isFile || (hasAuthority && !currentPath.isEmpty)) &&
          !currentPath.startsWith('/')) {
        currentPath = "/" + currentPath;
      }
      path = currentPath;
    }

    if (query != null || queryParameters != null) {
      query = _makeQuery(query, 0, _stringOrNullLength(query), queryParameters);
    } else {
      query = this._query;
    }

    if (fragment != null) {
      fragment = _makeFragment(fragment, 0, fragment.length);
    } else {
      fragment = this._fragment;
    }

    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
  }

  Uri removeFragment() {
    if (!this.hasFragment) return this;
    return _Uri._internal(scheme, _userInfo, _host, _port, path, _query, null);
  }

  static List<String> _computePathSegments(String pathToSplit) {
    if (pathToSplit.isNotEmpty && pathToSplit.codeUnitAt(0) == _SLASH) {
      pathToSplit = pathToSplit.substring(1);
    }
    return (pathToSplit.isEmpty)
        ? const <String>[]
        : List<String>.unmodifiable(
          pathToSplit.split("/").map(Uri.decodeComponent),
        );
  }

  static Map<String, List<String>> _computeQueryParametersAll(String? query) {
    if (query == null || query.isEmpty) return const <String, List<String>>{};
    Map<String, List<String>> queryParameterLists = _splitQueryStringAll(query);
    queryParameterLists.updateAll(_toUnmodifiableStringList);
    return Map<String, List<String>>.unmodifiable(queryParameterLists);
  }

  Uri normalizePath() {
    String path = _normalizePath(this.path, scheme, hasAuthority);
    if (identical(path, this.path)) return this;
    return this.replace(path: path);
  }

  static int? _makePort(int? port, String scheme) {
    // Perform scheme specific normalization.
    if (port != null && port == _defaultPort(scheme)) return null;
    return port;
  }

  /// Check and normalize a host name.
  ///
  /// If the host name starts and ends with '[' and ']', it is considered an
  /// IPv6 address. If [strictIPv6] is false, the address is also considered
  /// an IPv6 address if it contains any ':' character.
  ///
  /// If it is not an IPv6 address, it is case- and escape-normalized.
  /// This escapes all characters not valid in a reg-name,
  /// and converts all non-escape upper-case letters to lower-case.
  static String? _makeHost(String? host, int start, int end, bool strictIPv6) {
    // TODO(lrn): Should we normalize IPv6 addresses according to RFC 5952?
    if (host == null) return null;
    if (start == end) return "";
    // Host is an IPv6 address if it starts with '[' or contains a colon.
    if (host.codeUnitAt(start) == _LEFT_BRACKET) {
      if (host.codeUnitAt(end - 1) != _RIGHT_BRACKET) {
        _fail(host, start, 'Missing end `]` to match `[` in host');
      }
      String zoneID = "";
      int index = _checkZoneID(host, start + 1, end - 1);
      if (index < end - 1) {
        int zoneIDstart =
            (host.startsWith("25", index + 1)) ? index + 3 : index + 1;
        zoneID = _normalizeZoneID(host, zoneIDstart, end - 1, "%25");
      }
      Uri.parseIPv6Address(host, start + 1, index);
      // RFC 5952 requires hex digits to be lower case.
      return host.substring(start, index).toLowerCase() + zoneID + ']';
    }
    if (!strictIPv6) {
      // TODO(lrn): skip if too short to be a valid IPv6 address?
      for (int i = start; i < end; i++) {
        if (host.codeUnitAt(i) == _COLON) {
          String zoneID = "";
          int index = _checkZoneID(host, start, end);
          if (index < end) {
            int zoneIDstart =
                (host.startsWith("25", index + 1)) ? index + 3 : index + 1;
            zoneID = _normalizeZoneID(host, zoneIDstart, end, "%25");
          }
          Uri.parseIPv6Address(host, start, index);
          return '[${host.substring(start, index)}' + zoneID + ']';
        }
      }
    }
    return _normalizeRegName(host, start, end);
  }

  /// RFC 6874 check for ZoneID
  /// Return the index of first appeared `%`.
  static int _checkZoneID(String host, int start, int end) {
    int index = host.indexOf('%', start);
    index = (index >= start && index < end) ? index : end;
    return index;
  }

  static bool _isZoneIDChar(int char) {
    return char < 127 && (_charTables.codeUnitAt(char) & _zoneIDMask) != 0;
  }

  /// Validates and does case- and percent-encoding normalization.
  ///
  /// The same as [_normalizeOrSubstring]
  /// except this function does not convert characters to lower case.
  /// The [host] must be an RFC6874 "ZoneID".
  /// ZoneID = 1*(unreserved / pct-encoded)
  static String _normalizeZoneID(
    String host,
    int start,
    int end, [
    String prefix = '',
  ]) {
    StringBuffer? buffer;
    if (prefix != '') {
      buffer = StringBuffer(prefix);
    }
    int sectionStart = start;
    int index = start;
    // Whether all characters between sectionStart and index are normalized,
    bool isNormalized = true;

    while (index < end) {
      int char = host.codeUnitAt(index);
      if (char == _PERCENT) {
        String? replacement = _normalizeEscape(host, index, true);
        if (replacement == null && isNormalized) {
          index += 3;
          continue;
        }
        buffer ??= StringBuffer();
        String slice = host.substring(sectionStart, index);
        buffer.write(slice);
        int sourceLength = 3;
        if (replacement == null) {
          replacement = host.substring(index, index + 3);
        } else if (replacement == "%") {
          _fail(host, index, "ZoneID should not contain % anymore");
        }
        buffer.write(replacement);
        index += sourceLength;
        sectionStart = index;
        isNormalized = true;
      } else if (_isZoneIDChar(char)) {
        if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) {
          // Put initial slice in buffer and continue in non-normalized mode
          buffer ??= StringBuffer();
          if (sectionStart < index) {
            buffer.write(host.substring(sectionStart, index));
            sectionStart = index;
          }
          isNormalized = false;
        }
        index++;
      } else {
        int sourceLength = 1;
        if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
          int tail = host.codeUnitAt(index + 1);
          if ((tail & 0xFC00) == 0xDC00) {
            char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
            sourceLength = 2;
          }
        }
        String slice = host.substring(sectionStart, index);
        (buffer ??= StringBuffer())
          ..write(slice)
          ..write(_escapeChar(char));
        index += sourceLength;
        sectionStart = index;
      }
    }
    if (buffer == null) return host.substring(start, end);
    if (sectionStart < end) {
      String slice = host.substring(sectionStart, end);
      buffer.write(slice);
    }
    return buffer.toString();
  }

  static bool _isRegNameChar(int char) {
    return char < 127 && (_charTables.codeUnitAt(char) & _regNameMask) != 0;
  }

  /// Validates and does case- and percent-encoding normalization.
  ///
  /// The [host] must be an RFC3986 "reg-name". It is converted
  /// to lower case, and percent escapes are converted to either
  /// lower case unreserved characters or upper case escapes.
  static String _normalizeRegName(String host, int start, int end) {
    StringBuffer? buffer;
    int sectionStart = start;
    int index = start;
    // Whether all characters between sectionStart and index are normalized,
    bool isNormalized = true;

    while (index < end) {
      int char = host.codeUnitAt(index);
      if (char == _PERCENT) {
        // The _regNameMask table contains "%", so we check that first.
        String? replacement = _normalizeEscape(host, index, true);
        if (replacement == null && isNormalized) {
          index += 3;
          continue;
        }
        buffer ??= StringBuffer();
        String slice = host.substring(sectionStart, index);
        if (!isNormalized) slice = slice.toLowerCase();
        buffer.write(slice);
        int sourceLength = 3;
        if (replacement == null) {
          replacement = host.substring(index, index + 3);
        } else if (replacement == "%") {
          replacement = "%25";
          sourceLength = 1;
        }
        buffer.write(replacement);
        index += sourceLength;
        sectionStart = index;
        isNormalized = true;
      } else if (_isRegNameChar(char)) {
        if (isNormalized && _UPPER_CASE_A <= char && _UPPER_CASE_Z >= char) {
          // Put initial slice in buffer and continue in non-normalized mode
          buffer ??= StringBuffer();
          if (sectionStart < index) {
            buffer.write(host.substring(sectionStart, index));
            sectionStart = index;
          }
          isNormalized = false;
        }
        index++;
      } else if (_isGeneralDelimiter(char)) {
        _fail(host, index, "Invalid character");
      } else {
        int sourceLength = 1;
        if ((char & 0xFC00) == 0xD800 && (index + 1) < end) {
          int tail = host.codeUnitAt(index + 1);
          if ((tail & 0xFC00) == 0xDC00) {
            char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
            sourceLength = 2;
          }
        }
        String slice = host.substring(sectionStart, index);
        if (!isNormalized) slice = slice.toLowerCase();
        (buffer ??= StringBuffer())
          ..write(slice)
          ..write(_escapeChar(char));
        index += sourceLength;
        sectionStart = index;
      }
    }
    if (buffer == null) return host.substring(start, end);
    if (sectionStart < end) {
      String slice = host.substring(sectionStart, end);
      if (!isNormalized) slice = slice.toLowerCase();
      buffer.write(slice);
    }
    return buffer.toString();
  }

  /// Validates scheme characters and does case-normalization.
  ///
  /// Schemes are converted to lower case. They cannot contain escapes.
  static String _makeScheme(String scheme, int start, int end) {
    if (start == end) return "";
    final int firstCodeUnit = scheme.codeUnitAt(start);
    if (!_isAlphabeticCharacter(firstCodeUnit)) {
      _fail(scheme, start, "Scheme not starting with alphabetic character");
    }
    bool containsUpperCase = false;
    for (int i = start; i < end; i++) {
      final int codeUnit = scheme.codeUnitAt(i);
      if (!_isSchemeCharacter(codeUnit)) {
        _fail(scheme, i, "Illegal scheme character");
      }
      if (_UPPER_CASE_A <= codeUnit && codeUnit <= _UPPER_CASE_Z) {
        containsUpperCase = true;
      }
    }
    scheme = scheme.substring(start, end);
    if (containsUpperCase) scheme = scheme.toLowerCase();
    return _canonicalizeScheme(scheme);
  }

  /// Canonicalize a few often-used scheme strings.
  ///
  /// This improves memory usage and makes comparison faster.
  static String _canonicalizeScheme(String scheme) {
    if (scheme == "http") return "http";
    if (scheme == "file") return "file";
    if (scheme == "https") return "https";
    if (scheme == "package") return "package";
    return scheme;
  }

  static String _makeUserInfo(String? userInfo, int start, int end) {
    if (userInfo == null) return "";
    return _normalizeOrSubstring(userInfo, start, end, _userinfoMask);
  }

  static String _makePath(
    String? path,
    int start,
    int end,
    Iterable<String>? pathSegments,
    String scheme,
    bool hasAuthority,
  ) {
    bool isFile = (scheme == "file");
    bool ensureLeadingSlash = isFile || hasAuthority;
    String result;
    if (path == null) {
      if (pathSegments == null) return isFile ? "/" : "";
      result = pathSegments
          .map((s) => _uriEncode(_pathCharMask, s, utf8, false))
          .join("/");
    } else if (pathSegments != null) {
      throw ArgumentError('Both path and pathSegments specified');
    } else {
      result = _normalizeOrSubstring(
        path,
        start,
        end,
        _pathCharOrSlashMask,
        escapeDelimiters: true,
        replaceBackslash: true,
      );
    }
    if (result.isEmpty) {
      if (isFile) return "/";
    } else if (ensureLeadingSlash && !result.startsWith('/')) {
      result = "/" + result;
    }
    result = _normalizePath(result, scheme, hasAuthority);
    return result;
  }

  /// Performs path normalization (remove dot segments) on a path.
  ///
  /// If the URI has neither scheme nor authority, it's considered a
  /// "pure path" and normalization won't remove leading ".." segments.
  /// Otherwise it follows the RFC 3986 "remove dot segments" algorithm.
  static String _normalizePath(String path, String scheme, bool hasAuthority) {
    if (scheme.isEmpty &&
        !hasAuthority &&
        !path.startsWith('/') &&
        !path.startsWith(r'\')) {
      return _normalizeRelativePath(path, scheme.isNotEmpty || hasAuthority);
    }
    return _removeDotSegments(path);
  }

  static String? _makeQuery(
    String? query,
    int start,
    int end,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
  ) {
    if (query != null) {
      if (queryParameters != null) {
        throw ArgumentError('Both query and queryParameters specified');
      }
      return _normalizeOrSubstring(
        query,
        start,
        end,
        _queryCharMask,
        escapeDelimiters: true,
      );
    }
    if (queryParameters == null) return null;
    return _makeQueryFromParameters(queryParameters);
  }

  external static String _makeQueryFromParameters(
    Map<String, dynamic /*String?|Iterable<String>*/> queryParameters,
  );

  /// Default implementation of [_makeQueryFromParameters].
  ///
  /// This implementation is used from the patch for [_makeQueryFromParameters]
  /// where there is not a more efficient native implementation available.
  static String _makeQueryFromParametersDefault(
    Map<String, dynamic /*String?|Iterable<String>*/> queryParameters,
  ) {
    var result = StringBuffer();
    var separator = "";

    void writeParameter(String key, String? value) {
      result.write(separator);
      separator = "&";
      result.write(Uri.encodeQueryComponent(key));
      if (value != null && value.isNotEmpty) {
        result.write("=");
        result.write(Uri.encodeQueryComponent(value));
      }
    }

    queryParameters.forEach((key, value) {
      if (value == null || value is String) {
        writeParameter(key, value);
      } else {
        Iterable values = value;
        for (String value in values) {
          writeParameter(key, value);
        }
      }
    });
    return result.toString();
  }

  static String? _makeFragment(String? fragment, int start, int end) {
    if (fragment == null) return null;
    return _normalizeOrSubstring(
      fragment,
      start,
      end,
      _queryCharMask,
      escapeDelimiters: true,
    );
  }

  /// Performs RFC 3986 Percent-Encoding Normalization.
  ///
  /// Returns a replacement string that should replace the original escape.
  /// Returns null if no replacement is necessary because the escape is
  /// not for an unreserved character and is already non-lower-case.
  ///
  /// Returns "%" if the escape is invalid (not two valid hex digits following
  /// the percent sign). The calling code should replace the percent
  /// sign with "%25", but leave the following two characters unmodified.
  ///
  /// If [lowerCase] is true, a single character returned is always lower case,
  static String? _normalizeEscape(String source, int index, bool lowerCase) {
    assert(source.codeUnitAt(index) == _PERCENT);
    if (index + 2 >= source.length) {
      return "%"; // Marks the escape as invalid.
    }
    int firstDigit = source.codeUnitAt(index + 1);
    int secondDigit = source.codeUnitAt(index + 2);
    int firstDigitValue = hexDigitValue(firstDigit);
    int secondDigitValue = hexDigitValue(secondDigit);
    if (firstDigitValue < 0 || secondDigitValue < 0) {
      return "%"; // Marks the escape as invalid.
    }
    int value = firstDigitValue * 16 + secondDigitValue;
    if (_isUnreservedChar(value)) {
      if (lowerCase && _UPPER_CASE_A <= value && _UPPER_CASE_Z >= value) {
        value |= 0x20;
      }
      return String.fromCharCode(value);
    }
    if (firstDigit >= _LOWER_CASE_A || secondDigit >= _LOWER_CASE_A) {
      // Either digit is lower case.
      return source.substring(index, index + 3).toUpperCase();
    }
    // Escape is retained, and is already non-lower case, so return null to
    // represent "no replacement necessary".
    return null;
  }

  static String _escapeChar(int char) {
    assert(char <= 0x10ffff); // It's a valid unicode code point.
    List<int> codeUnits;
    if (char <= 0x7f) {
      // ASCII, a single percent encoded sequence.
      codeUnits = Uint8List(3);
      codeUnits[0] = _PERCENT;
      codeUnits[1] = _hexDigits.codeUnitAt(char >> 4);
      codeUnits[2] = _hexDigits.codeUnitAt(char & 0xf);
    } else {
      // Do UTF-8 encoding of character, then percent encode bytes.
      int flag = 0xc0; // The high-bit markers on the first byte of UTF-8.
      int encodedBytes = 2;
      if (char > 0x7ff) {
        flag = 0xe0;
        encodedBytes = 3;
        if (char > 0xffff) {
          encodedBytes = 4;
          flag = 0xf0;
        }
      }
      codeUnits = Uint8List(3 * encodedBytes);
      int index = 0;
      while (--encodedBytes >= 0) {
        int byte = ((char >> (6 * encodedBytes)) & 0x3f) | flag;
        codeUnits[index] = _PERCENT;
        codeUnits[index + 1] = _hexDigits.codeUnitAt(byte >> 4);
        codeUnits[index + 2] = _hexDigits.codeUnitAt(byte & 0xf);
        index += 3;
        flag = 0x80; // Following bytes have only high bit set.
      }
    }
    return String.fromCharCodes(codeUnits);
  }

  /// Normalizes using [_normalize] or returns substring of original.
  ///
  /// If [_normalize] returns `null` (original content is already normalized),
  /// this methods returns the substring if [component] from [start] to [end].
  static String _normalizeOrSubstring(
    String component,
    int start,
    int end,
    int charMask, {
    bool escapeDelimiters = false,
    bool replaceBackslash = false,
  }) {
    return _normalize(
          component,
          start,
          end,
          charMask,
          escapeDelimiters: escapeDelimiters,
          replaceBackslash: replaceBackslash,
        ) ??
        component.substring(start, end);
  }

  /// Runs through component checking that each character is valid and
  /// normalizes percent escapes.
  ///
  /// Uses [charTable] to check if a non-`%` character is allowed.
  /// Each `%` character must be followed by two hex digits.
  /// If the hex-digits are lowercase letters, they are converted to
  /// uppercase.
  ///
  /// Returns `null` if the original content was already normalized.
  static String? _normalize(
    String component,
    int start,
    int end,
    int charMask, {
    bool escapeDelimiters = false,
    bool replaceBackslash = false,
  }) {
    StringBuffer? buffer;
    int sectionStart = start;
    int index = start;
    // Loop while characters are valid and escapes correct and upper-case.
    while (index < end) {
      int char = component.codeUnitAt(index);
      if (char < 127 && (_charTables.codeUnitAt(char) & charMask) != 0) {
        index++;
      } else {
        String? replacement;
        int sourceLength;
        if (char == _PERCENT) {
          replacement = _normalizeEscape(component, index, false);
          // Returns null if we should keep the existing escape.
          if (replacement == null) {
            index += 3;
            continue;
          }
          // Returns "%" if we should escape the existing percent.
          if ("%" == replacement) {
            replacement = "%25";
            sourceLength = 1;
          } else {
            sourceLength = 3;
          }
        } else if (char == _BACKSLASH && replaceBackslash) {
          replacement = "/";
          sourceLength = 1;
        } else if (!escapeDelimiters && _isGeneralDelimiter(char)) {
          _fail(component, index, "Invalid character");
          throw "unreachable"; // TODO(lrn): Remove when Never-returning functions are recognized as throwing.
        } else {
          sourceLength = 1;
          if ((char & 0xFC00) == 0xD800) {
            // Possible lead surrogate.
            if (index + 1 < end) {
              int tail = component.codeUnitAt(index + 1);
              if ((tail & 0xFC00) == 0xDC00) {
                // Tail surrogate.
                sourceLength = 2;
                char = 0x10000 + ((char & 0x3ff) << 10) + (tail & 0x3ff);
              }
            }
          }
          replacement = _escapeChar(char);
        }
        (buffer ??= StringBuffer())
          ..write(component.substring(sectionStart, index))
          ..write(replacement);
        index += sourceLength;
        sectionStart = index;
      }
    }
    if (buffer == null) {
      return null;
    }
    if (sectionStart < end) {
      buffer.write(component.substring(sectionStart, end));
    }
    return buffer.toString();
  }

  static bool _isSchemeCharacter(int char) {
    return char < 128 && ((_charTables.codeUnitAt(char) & _schemeMask) != 0);
  }

  static bool _isGeneralDelimiter(int char) {
    return char <= _RIGHT_BRACKET &&
        ((_charTables.codeUnitAt(char) & _genDelimitersMask) != 0);
  }

  /// Whether the URI is absolute.
  bool get isAbsolute => scheme != "" && fragment == "";

  String _mergePaths(String base, String reference) {
    // Optimize for the case: absolute base, reference beginning with "../".
    int backCount = 0;
    int refStart = 0;
    // Count number of "../" at beginning of reference.
    while (reference.startsWith("../", refStart)) {
      refStart += 3;
      backCount++;
    }

    // Drop last segment - everything after last '/' of base.
    int baseEnd = base.lastIndexOf('/');
    // Drop extra segments for each leading "../" of reference.
    while (baseEnd > 0 && backCount > 0) {
      int newEnd = base.lastIndexOf('/', baseEnd - 1);
      if (newEnd < 0) {
        break;
      }
      int delta = baseEnd - newEnd;
      // If we see a "." or ".." segment in base, stop here and let
      // _removeDotSegments handle it.
      if ((delta == 2 || delta == 3) &&
          base.codeUnitAt(newEnd + 1) == _DOT &&
          (delta == 2 || base.codeUnitAt(newEnd + 2) == _DOT)) {
        break;
      }
      baseEnd = newEnd;
      backCount--;
    }
    return base.replaceRange(
      baseEnd + 1,
      null,
      reference.substring(refStart - 3 * backCount),
    );
  }

  /// Make a guess at whether a path contains a `..` or `.` segment.
  ///
  /// This is a primitive test that can cause false positives.
  /// It's only used to avoid a more expensive operation in the case where
  /// it's not necessary.
  static bool _mayContainDotSegments(String path) {
    if (path.startsWith('.')) return true;
    int index = path.indexOf("/.");
    return index != -1;
  }

  /// Removes '.' and '..' segments from a path.
  ///
  /// Follows the RFC 2986 "remove dot segments" algorithm.
  /// This algorithm is only used on paths of URIs with a scheme,
  /// and it treats the path as if it is absolute (leading '..' are removed).
  static String _removeDotSegments(String path) {
    if (!_mayContainDotSegments(path)) return path;
    assert(path.isNotEmpty); // An empty path would not have dot segments.
    List<String> output = [];
    bool appendSlash = false;
    for (String segment in path.split("/")) {
      appendSlash = false;
      if (segment == "..") {
        if (output.isNotEmpty) {
          output.removeLast();
          if (output.isEmpty) {
            output.add("");
          }
        }
        appendSlash = true;
      } else if ("." == segment) {
        appendSlash = true;
      } else {
        output.add(segment);
      }
    }
    if (appendSlash) output.add("");
    return output.join("/");
  }

  /// Removes all `.` segments and any non-leading `..` segments.
  ///
  /// If the path starts with something that looks like a scheme,
  /// and [allowScheme] is false, the colon is escaped.
  ///
  /// Removing the ".." from a "bar/foo/.." sequence results in "bar/"
  /// (trailing "/"). If the entire path is removed (because it contains as
  /// many ".." segments as real segments), the result is "./".
  /// This is different from an empty string, which represents "no path"
  /// when you resolve it against a base URI with a path with a non-empty
  /// final segment.
  static String _normalizeRelativePath(String path, bool allowScheme) {
    assert(!path.startsWith('/')); // Only get called for relative paths.
    if (!_mayContainDotSegments(path)) {
      if (!allowScheme) path = _escapeScheme(path);
      return path;
    }
    assert(path.isNotEmpty); // An empty path would not have dot segments.
    List<String> output = [];
    bool appendSlash = false;
    for (String segment in path.split("/")) {
      appendSlash = false;
      if (".." == segment) {
        if (!output.isEmpty && output.last != "..") {
          output.removeLast();
          appendSlash = true;
        } else {
          output.add("..");
        }
      } else if ("." == segment) {
        appendSlash = true;
      } else {
        output.add(segment);
      }
    }
    if (output.isEmpty || (output.length == 1 && output[0].isEmpty)) {
      return "./";
    }
    if (appendSlash || output.last == '..') output.add("");
    if (!allowScheme) output[0] = _escapeScheme(output[0]);
    return output.join("/");
  }

  /// If [path] starts with a valid scheme, escape the percent.
  static String _escapeScheme(String path) {
    if (path.length >= 2 && _isAlphabeticCharacter(path.codeUnitAt(0))) {
      for (int i = 1; i < path.length; i++) {
        int char = path.codeUnitAt(i);
        if (char == _COLON) {
          return "${path.substring(0, i)}%3A${path.substring(i + 1)}";
        }
        if (char > 127 || ((_charTables.codeUnitAt(char) & _schemeMask) == 0)) {
          break;
        }
      }
    }
    return path;
  }

  Uri resolve(String reference) {
    return resolveUri(Uri.parse(reference));
  }

  // The index of the `/` after the package name of a package URI.
  //
  // Value is negative if the URI is not a valid package URI:
  // * Scheme must be "package".
  // * No authority.
  // * Path starts with "something/".
  // * where "something" is not all "." characters,
  // * and contains no escapes or colons.
  //
  // The characters are necessarily valid path characters.
  static int _packageNameEnd(Uri uri, String path) {
    if (uri.isScheme("package") && !uri.hasAuthority) {
      return _skipPackageNameChars(path, 0, path.length);
    }
    return -1;
  }

  Uri resolveUri(Uri reference) {
    // From RFC 3986.
    String targetScheme;
    String targetUserInfo = "";
    String? targetHost;
    int? targetPort;
    String targetPath;
    String? targetQuery;
    // Position up to which values are known to already be normalized,
    // because the value is taken from this `_Uri`
    // If any part of the path is taken from a `reference` which is not
    // a platform URI, and therefore not known to be canonicalized to the
    // standard of platform URIs, the combined path counts as potentially
    // non-normalized.
    const int atStart =
            0, // Nothing taken from this URI.
        afterScheme =
            1, // Scheme comes from this URI.
        afterAuthority =
            2, // Scheme and authority comes from this URI.
        afterPath =
            3, // The path, and everything before, is from this URI.
        afterQuery = 4; // Everything except fragment is from this URI.
    int split = atStart;

    if (reference.scheme.isNotEmpty) {
      if (reference is _PlatformUri) return reference;
      targetScheme = reference.scheme;
      if (reference.hasAuthority) {
        targetUserInfo = reference.userInfo;
        targetHost = reference.host;
        targetPort = reference.hasPort ? reference.port : null;
      }
      targetPath = _removeDotSegments(reference.path);
      if (reference.hasQuery) {
        targetQuery = reference.query;
      }
    } else {
      targetScheme = this.scheme;
      if (reference.hasAuthority) {
        if (reference is _PlatformUri) {
          return reference.replace(scheme: targetScheme);
        }
        targetUserInfo = reference.userInfo;
        targetHost = reference.host;
        targetPort = _makePort(
          reference.hasPort ? reference.port : null,
          targetScheme,
        );
        targetPath = _removeDotSegments(reference.path);
        if (reference.hasQuery) targetQuery = reference.query;
        split = afterScheme;
      } else {
        targetUserInfo = this._userInfo;
        targetHost = this._host;
        targetPort = this._port;
        if (reference.hasEmptyPath) {
          targetPath = this.path;
          if (reference.hasQuery) {
            split = afterPath;
            targetQuery = reference.query;
          } else {
            targetQuery = this._query;
            split = afterQuery;
          }
        } else {
          String basePath = this.path;
          int packageNameEnd = _packageNameEnd(this, basePath);
          split = afterAuthority;
          if (packageNameEnd > 0) {
            assert(targetScheme == "package");
            assert(!this.hasAuthority);
            assert(!this.hasEmptyPath);
            // Merging a path into a package URI.
            String packageName = basePath.substring(0, packageNameEnd);
            if (reference.hasAbsolutePath) {
              targetPath = packageName + _removeDotSegments(reference.path);
            } else {
              targetPath =
                  packageName +
                  _removeDotSegments(
                    _mergePaths(
                      basePath.substring(packageName.length),
                      reference.path,
                    ),
                  );
            }
          } else if (reference.hasAbsolutePath) {
            targetPath = _removeDotSegments(reference.path);
          } else {
            // This is the RFC 3986 behavior for merging.
            if (this.hasEmptyPath) {
              if (!this.hasAuthority) {
                if (!this.hasScheme) {
                  // Keep the path relative if no scheme or authority.
                  targetPath = reference.path;
                } else {
                  // Remove leading dot-segments if the path is put
                  // beneath a scheme.
                  targetPath = _removeDotSegments(reference.path);
                }
              } else {
                // RFC algorithm for base with authority and empty path.
                targetPath = _removeDotSegments("/" + reference.path);
              }
            } else {
              var mergedPath = _mergePaths(this.path, reference.path);
              if (this.hasScheme || this.hasAuthority || this.hasAbsolutePath) {
                targetPath = _removeDotSegments(mergedPath);
              } else {
                // Non-RFC 3986 behavior.
                // If both base and reference are relative paths,
                // allow the merged path to start with "..".
                // The RFC only specifies the case where the base has a scheme.
                targetPath = _normalizeRelativePath(
                  mergedPath,
                  this.hasScheme || this.hasAuthority,
                );
              }
            }
          }
          if (reference.hasQuery) {
            targetQuery = reference.query;
          }
        }
      }
    }
    String? fragment = reference.hasFragment ? reference.fragment : null;
    if (reference is! _PlatformUri) {
      // Don't trust values coming from `reference` to be normalized.
      if (split == atStart) {
        targetScheme = _makeScheme(targetScheme, 0, targetScheme.length);
      }
      if (split <= afterScheme) {
        if (targetUserInfo != null) {
          targetUserInfo = _makeUserInfo(
            targetUserInfo,
            0,
            targetUserInfo.length,
          );
        }
        if (targetPort != null) {
          targetPort = _makePort(targetPort, targetScheme);
        }
        if (targetHost != null && targetHost.isNotEmpty) {
          targetHost = _makeHost(targetHost, 0, targetHost.length, false);
        }
      }
      if (split <= afterPath) {
        targetPath = _makePath(
          targetPath,
          0,
          targetPath.length,
          null,
          targetScheme,
          targetHost != null,
        );
      }
      if (split <= afterPath && targetQuery != null) {
        targetQuery = _makeQuery(targetQuery, 0, targetQuery.length, null);
      }
      if (fragment != null) {
        fragment = _makeFragment(fragment, 0, fragment.length);
      }
    }
    return _Uri._internal(
      targetScheme,
      targetUserInfo,
      targetHost,
      targetPort,
      targetPath,
      targetQuery,
      fragment,
    );
  }

  bool get hasScheme => scheme.isNotEmpty;

  bool get hasAuthority => _host != null;

  bool get hasPort => _port != null;

  bool get hasQuery => _query != null;

  bool get hasFragment => _fragment != null;

  bool get hasEmptyPath => path.isEmpty;

  bool get hasAbsolutePath => path.startsWith('/');

  String get origin {
    if (scheme == "") {
      throw StateError("Cannot use origin without a scheme: $this");
    }
    if (scheme != "http" && scheme != "https") {
      throw StateError(
        "Origin is only applicable schemes http and https: $this",
      );
    }
    String? host = _host;
    if (host == null || host == "") {
      throw StateError(
        "A $scheme: URI should have a non-empty host name: $this",
      );
    }
    int? port = _port;
    if (port == null) return "$scheme://$host";
    return "$scheme://$host:$port";
  }

  String toFilePath({bool? windows}) {
    if (scheme != "" && scheme != "file") {
      throw UnsupportedError("Cannot extract a file path from a $scheme URI");
    }
    if (query != "") {
      throw UnsupportedError(
        "Cannot extract a file path from a URI with a query component",
      );
    }
    if (fragment != "") {
      throw UnsupportedError(
        "Cannot extract a file path from a URI with a fragment component",
      );
    }
    return (windows ?? _isWindows) ? _toWindowsFilePath(this) : _toFilePath();
  }

  String _toFilePath() {
    if (hasAuthority && host != "") {
      throw UnsupportedError(
        "Cannot extract a non-Windows file path from a file URI "
        "with an authority",
      );
    }
    // Use path segments to have any escapes unescaped.
    var pathSegments = this.pathSegments;
    _checkNonWindowsPathReservedCharacters(pathSegments, false);
    var result = StringBuffer();
    if (hasAbsolutePath) result.write("/");
    result.writeAll(pathSegments, "/");
    return result.toString();
  }

  static String _toWindowsFilePath(Uri uri) {
    bool hasDriveLetter = false;
    var segments = uri.pathSegments;
    if (segments.length > 0 &&
        segments[0].length == 2 &&
        segments[0].codeUnitAt(1) == _COLON) {
      _checkWindowsDriveLetter(segments[0].codeUnitAt(0), false);
      _checkWindowsPathReservedCharacters(segments, false, 1);
      hasDriveLetter = true;
    } else {
      _checkWindowsPathReservedCharacters(segments, false, 0);
    }
    var result = StringBuffer();
    if (uri.hasAbsolutePath && !hasDriveLetter) result.write(r"\");
    if (uri.hasAuthority) {
      var host = uri.host;
      if (host.isNotEmpty) {
        result.write(r"\");
        result.write(host);
        result.write(r"\");
      }
    }
    result.writeAll(segments, r"\");
    if (hasDriveLetter && segments.length == 1) result.write(r"\");
    return result.toString();
  }

  void _writeAuthority(StringSink ss) {
    if (_userInfo.isNotEmpty) {
      ss.write(_userInfo);
      ss.write("@");
    }
    if (_host != null) ss.write(_host);
    if (_port != null) {
      ss.write(":");
      ss.write(_port);
    }
  }

  /// Access the structure of a `data:` URI.
  ///
  /// Returns a [UriData] object for `data:` URIs and `null` for all other
  /// URIs.
  /// The [UriData] object can be used to access the media type and data
  /// of a `data:` URI.
  UriData? get data => (scheme == "data") ? UriData.fromUri(this) : null;

  String toString() => _text;

  String _initializeText() {
    StringBuffer sb = StringBuffer();
    if (scheme.isNotEmpty)
      sb
        ..write(scheme)
        ..write(":");
    if (hasAuthority || (scheme == "file")) {
      // File URIS always have the authority, even if it is empty.
      // The empty URI means "localhost".
      sb.write("//");
      _writeAuthority(sb);
    }
    sb.write(path);
    if (_query != null)
      sb
        ..write("?")
        ..write(_query);
    if (_fragment != null)
      sb
        ..write("#")
        ..write(_fragment);
    return sb.toString();
  }

  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Uri &&
        scheme == other.scheme &&
        hasAuthority == other.hasAuthority &&
        userInfo == other.userInfo &&
        host == other.host &&
        port == other.port &&
        path == other.path &&
        hasQuery == other.hasQuery &&
        query == other.query &&
        hasFragment == other.hasFragment &&
        fragment == other.fragment;
  }

  static List<String> _createList() => <String>[];

  static Map<String, List<String>> _splitQueryStringAll(
    String query, {
    Encoding encoding = utf8,
  }) {
    var result = <String, List<String>>{};
    int i = 0;
    int start = 0;
    int equalsIndex = -1;

    void parsePair(int start, int equalsIndex, int end) {
      String key;
      String value;
      if (start == end) return;
      if (equalsIndex < 0) {
        key = _uriDecode(query, start, end, encoding, true);
        value = "";
      } else {
        key = _uriDecode(query, start, equalsIndex, encoding, true);
        value = _uriDecode(query, equalsIndex + 1, end, encoding, true);
      }
      result.putIfAbsent(key, _createList).add(value);
    }

    while (i < query.length) {
      int char = query.codeUnitAt(i);
      if (char == _EQUALS) {
        if (equalsIndex < 0) equalsIndex = i;
      } else if (char == _AMPERSAND) {
        parsePair(start, equalsIndex, i);
        start = i + 1;
        equalsIndex = -1;
      }
      i++;
    }
    parsePair(start, equalsIndex, i);
    return result;
  }

  external static String _uriEncode(
    int canonicalMask,
    String text,
    Encoding encoding,
    bool spaceToPlus,
  );

  /// Convert a byte (2 character hex sequence) in string [s] starting
  /// at position [pos] to its ordinal value
  static int _hexCharPairToByte(String s, int pos) {
    int byte = 0;
    for (int i = 0; i < 2; i++) {
      var charCode = s.codeUnitAt(pos + i);
      if (0x30 <= charCode && charCode <= 0x39) {
        byte = byte * 16 + charCode - 0x30;
      } else {
        // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66).
        charCode |= 0x20;
        if (0x61 <= charCode && charCode <= 0x66) {
          byte = byte * 16 + charCode - 0x57;
        } else {
          throw ArgumentError("Invalid URL encoding");
        }
      }
    }
    return byte;
  }

  /// Uri-decode a percent-encoded string.
  ///
  /// It unescapes the string [text] and returns the unescaped string.
  ///
  /// This function is similar to the JavaScript-function `decodeURI`.
  ///
  /// If [plusToSpace] is `true`, plus characters will be converted to spaces.
  ///
  /// The decoder will create a byte-list of the percent-encoded parts, and then
  /// decode the byte-list using [encoding]. The default encoding is UTF-8.
  static String _uriDecode(
    String text,
    int start,
    int end,
    Encoding encoding,
    bool plusToSpace,
  ) {
    assert(0 <= start);
    assert(start <= end);
    assert(end <= text.length);
    // First check whether there is any characters which need special handling.
    bool simple = true;
    for (int i = start; i < end; i++) {
      var codeUnit = text.codeUnitAt(i);
      if (codeUnit > 127 ||
          codeUnit == _PERCENT ||
          (plusToSpace && codeUnit == _PLUS)) {
        simple = false;
        break;
      }
    }
    List<int> bytes;
    if (simple) {
      if (utf8 == encoding || latin1 == encoding || ascii == encoding) {
        return text.substring(start, end);
      } else {
        bytes = text.substring(start, end).codeUnits;
      }
    } else {
      bytes = <int>[];
      for (int i = start; i < end; i++) {
        var codeUnit = text.codeUnitAt(i);
        if (codeUnit > 127) {
          throw ArgumentError("Illegal percent encoding in URI");
        }
        if (codeUnit == _PERCENT) {
          if (i + 3 > text.length) {
            throw ArgumentError('Truncated URI');
          }
          bytes.add(_hexCharPairToByte(text, i + 1));
          i += 2;
        } else if (plusToSpace && codeUnit == _PLUS) {
          bytes.add(_SPACE);
        } else {
          bytes.add(codeUnit);
        }
      }
    }
    return encoding.decode(bytes);
  }

  static bool _isAlphabeticCharacter(int codeUnit) {
    var lowerCase = codeUnit | 0x20;
    return (_LOWER_CASE_A <= lowerCase && lowerCase <= _LOWER_CASE_Z);
  }

  static bool _isUnreservedChar(int char) {
    return char < 127 &&
        ((_charTables.codeUnitAt(char) & _unreservedMask) != 0);
  }
}

// --------------------------------------------------------------------
// Data URI
// --------------------------------------------------------------------

/// A way to access the structure of a `data:` URI.
///
/// Data URIs are non-hierarchical URIs that can contain any binary data.
/// They are defined by [RFC 2397](https://tools.ietf.org/html/rfc2397).
///
/// This class allows parsing the URI text, extracting individual parts of the
/// URI, as well as building the URI text from structured parts.
final class UriData {
  static const int _noScheme = -1;

  /// Contains the text content of a `data:` URI, with or without a
  /// leading `data:`.
  ///
  /// If [_separatorIndices] starts with `4` (the index of the `:`), then
  /// there is a leading `data:`, otherwise [_separatorIndices] starts with
  /// `-1`.
  final String _text;

  /// List of the separators (';', '=' and ',') in the text.
  ///
  /// Starts with the index of the `:` in `data:` of the mimeType.
  /// That is always either -1 or 4, depending on whether `_text` includes the
  /// `data:` scheme or not.
  ///
  /// The first separator ends the mime type. We don't bother with finding
  /// the '/' inside the mime type.
  ///
  /// Each two separators after that mark a parameter key and value.
  ///
  /// If there is a single separator left, it ends the "base64" marker.
  ///
  /// So the following separators are found for a text:
  /// ```plaintext
  /// data:text/plain;foo=bar;base64,ARGLEBARGLE=
  ///     ^          ^   ^   ^      ^
  /// ```
  final List<int> _separatorIndices;

  /// Cache of the result returned by [uri].
  Uri? _uriCache;

  UriData._(this._text, this._separatorIndices, this._uriCache);

  // Avoid shadowing by argument.
  static const Base64Codec _base64 = base64;

  /// Creates a `data:` URI containing the [content] string.
  ///
  /// Equivalent to `Uri.dataFromString(...).data`, but may
  /// be more efficient if the [uri] itself isn't used.
  factory UriData.fromString(
    String content, {
    String? mimeType,
    Encoding? encoding,
    Map<String, String>? parameters,
    bool base64 = false,
  }) {
    StringBuffer buffer = StringBuffer();
    List<int> indices = [_noScheme];
    String? charsetName = parameters?["charset"];
    String? encodingName;
    if (encoding == null) {
      if (charsetName != null) {
        encoding = Encoding.getByName(charsetName);
      }
    } else if (charsetName == null) {
      // Non-null only if parameters does not contain "charset".
      encodingName = encoding.name;
    }
    encoding ??= ascii;
    _writeUri(mimeType, encodingName, parameters, buffer, indices);
    indices.add(buffer.length);
    if (base64) {
      buffer.write(';base64,');
      indices.add(buffer.length - 1);
      buffer.write(encoding.fuse(_base64).encode(content));
    } else {
      buffer.write(',');
      _uriEncodeBytes(_uricMask, encoding.encode(content), buffer);
    }
    return UriData._(buffer.toString(), indices, null);
  }

  /// Creates a `data:` URI containing an encoding of [bytes].
  ///
  /// Equivalent to `Uri.dataFromBytes(...).data`, but may
  /// be more efficient if the [uri] itself isn't used.
  factory UriData.fromBytes(
    List<int> bytes, {
    String mimeType = "application/octet-stream",
    Map<String, String>? parameters,
    bool percentEncoded = false,
  }) {
    StringBuffer buffer = StringBuffer();
    List<int> indices = [_noScheme];
    _writeUri(mimeType, null, parameters, buffer, indices);
    indices.add(buffer.length);
    if (percentEncoded) {
      buffer.write(',');
      _uriEncodeBytes(_uricMask, bytes, buffer);
    } else {
      buffer.write(';base64,');
      indices.add(buffer.length - 1);
      _base64.encoder
          .startChunkedConversion(StringConversionSink.fromStringSink(buffer))
          .addSlice(bytes, 0, bytes.length, true);
    }

    return UriData._(buffer.toString(), indices, null);
  }

  /// Creates a `DataUri` from a [Uri] which must have `data` as [Uri.scheme].
  ///
  /// The [uri] must have scheme `data` and no authority or fragment,
  /// and the path (concatenated with the query, if there is one) must be valid
  /// as data URI content with the same rules as [parse].
  factory UriData.fromUri(Uri uri) {
    if (!uri.isScheme("data")) {
      throw ArgumentError.value(uri, "uri", "Scheme must be 'data'");
    }
    if (uri.hasAuthority) {
      throw ArgumentError.value(uri, "uri", "Data uri must not have authority");
    }
    if (uri.hasFragment) {
      throw ArgumentError.value(
        uri,
        "uri",
        "Data uri must not have a fragment part",
      );
    }
    if (!uri.hasQuery) {
      return _parse(uri.path, 0, uri);
    }
    // Includes path and query (and leading "data:").
    return _parse(uri.toString(), 5, uri);
  }

  /// Writes the initial part of a `data:` uri, from after the "data:"
  /// until just before the ',' before the data, or before a `;base64,`
  /// marker.
  ///
  /// If an [indices] list is passed, separator indices are stored in that
  /// list.
  static void _writeUri(
    String? mimeType,
    String? charsetName,
    Map<String, String>? parameters,
    StringBuffer buffer,
    List<int>? indices,
  ) {
    if (mimeType == null || _caseInsensitiveEquals("text/plain", mimeType)) {
      mimeType = "";
    }

    if (mimeType.isEmpty || identical(mimeType, "application/octet-stream")) {
      buffer.write(mimeType); // Common cases need no escaping.
    } else {
      int slashIndex = _validateMimeType(mimeType);
      if (slashIndex < 0) {
        throw ArgumentError.value(mimeType, "mimeType", "Invalid MIME type");
      }
      buffer.write(
        _Uri._uriEncode(
          _tokenCharMask,
          mimeType.substring(0, slashIndex),
          utf8,
          false,
        ),
      );
      buffer.write("/");
      buffer.write(
        _Uri._uriEncode(
          _tokenCharMask,
          mimeType.substring(slashIndex + 1),
          utf8,
          false,
        ),
      );
    }
    if (charsetName != null) {
      indices
        ?..add(buffer.length)
        ..add(buffer.length + 8);
      buffer.write(";charset=");
      buffer.write(_Uri._uriEncode(_tokenCharMask, charsetName, utf8, false));
    }
    parameters?.forEach((key, value) {
      if (key.isEmpty) {
        throw ArgumentError.value("", "Parameter names must not be empty");
      }
      if (value.isEmpty) {
        throw ArgumentError.value(
          "",
          "Parameter values must not be empty",
          'parameters["$key"]',
        );
      }
      indices?.add(buffer.length);
      buffer.write(';');
      // Encode any non-RFC2045-token character and both '%' and '#'.
      buffer.write(_Uri._uriEncode(_tokenCharMask, key, utf8, false));
      indices?.add(buffer.length);
      buffer.write('=');
      buffer.write(_Uri._uriEncode(_tokenCharMask, value, utf8, false));
    });
  }

  /// Checks mimeType is valid-ish (`token '/' token`).
  ///
  /// Returns the index of the slash, or -1 if the mime type is not
  /// considered valid.
  ///
  /// Currently only looks for slashes, all other characters will be
  /// percent-encoded as UTF-8 if necessary.
  static int _validateMimeType(String mimeType) {
    int slashIndex = -1;
    for (int i = 0; i < mimeType.length; i++) {
      var char = mimeType.codeUnitAt(i);
      if (char != _SLASH) continue;
      if (slashIndex < 0) {
        slashIndex = i;
        continue;
      }
      return -1;
    }
    return slashIndex;
  }

  /// Parses a string as a `data` URI.
  ///
  /// The string must have the format:
  ///
  /// ```plaintext
  /// 'data:' (type '/' subtype)? (';' attribute '=' value)* (';base64')? ',' data
  /// ````
  ///
  /// where `type`, `subtype`, `attribute` and `value` are specified in RFC-2045,
  /// and `data` is a sequence of URI-characters (RFC-2396 `uric`).
  ///
  /// This means that all the characters must be ASCII, but the URI may contain
  /// percent-escapes for non-ASCII byte values that need an interpretation
  /// to be converted to the corresponding string.
  ///
  /// Parsing checks that Base64 encoded data is valid, and it normalizes it
  /// to use the default Base64 alphabet and to use padding.
  /// Non-Base64 data is escaped using percent-escapes as necessary to make
  /// it valid, and existing escapes are case normalized.
  ///
  /// Accessing the individual parts may fail later if they turn out to have
  /// content that cannot be decoded successfully as a string, for example if
  /// existing percent escapes represent bytes that cannot be decoded
  /// by the chosen [Encoding] (see [contentAsString]).
  ///
  /// A [FormatException] is thrown if [uri] is not a valid data URI.
  static UriData parse(String uri) {
    if (uri.length >= 5) {
      int dataDelta = _startsWithData(uri, 0);
      if (dataDelta == 0) {
        // Exact match on "data:".
        return _parse(uri, 5, null);
      }
      if (dataDelta == 0x20) {
        // Starts with a non-normalized "data" scheme containing upper-case
        // letters. Parse anyway, but throw away the scheme.
        return _parse(uri.substring(5), 0, null);
      }
    }
    throw FormatException("Does not start with 'data:'", uri, 0);
  }

  /// The [Uri] that this `UriData` is giving access to.
  ///
  /// Returns a `Uri` with scheme `data` and the remainder of the data URI
  /// as path.
  Uri get uri {
    return _uriCache ??= _computeUri();
  }

  Uri _computeUri() {
    String path = _text;
    String? query;
    int colonIndex = _separatorIndices[0];
    int queryIndex = _text.indexOf('?', colonIndex + 1);
    int end = _text.length;
    if (queryIndex >= 0) {
      query = _Uri._normalizeOrSubstring(
        _text,
        queryIndex + 1,
        end,
        _queryCharMask,
      );
      end = queryIndex;
    }
    path = _Uri._normalizeOrSubstring(
      _text,
      colonIndex + 1,
      end,
      _pathCharOrSlashMask,
    );
    return _DataUri(this, path, query);
  }

  /// The MIME type of the data URI.
  ///
  /// A data URI consists of a "media type" followed by data.
  /// The media type starts with a MIME type and can be followed by
  /// extra parameters.
  /// If the MIME type representation in the URI text contains URI escapes,
  /// they are unescaped in the returned string.
  /// If the value contain non-ASCII percent escapes, they are decoded as UTF-8.
  ///
  /// Example:
  /// ```
  /// data:text/plain;charset=utf-8,Hello%20World!
  /// ```
  /// This data URI has the media type `text/plain;charset=utf-8`, which is the
  /// MIME type `text/plain` with the parameter `charset` with value `utf-8`.
  /// See [RFC 2045](https://tools.ietf.org/html/rfc2045) for more detail.
  ///
  /// If the first part of the data URI is empty, it defaults to `text/plain`.
  String get mimeType {
    int start = _separatorIndices[0] + 1;
    int end = _separatorIndices[1];
    if (start == end) return "text/plain";
    return _Uri._uriDecode(_text, start, end, utf8, false);
  }

  /// Whether the [UriData.mimeType] is equal to [mimeType].
  ///
  /// Compares the `data:` URI's MIME type to [mimeType] with a case-
  /// insensitive comparison which ignores the case of ASCII letters.
  ///
  /// An empty [mimeType] is considered equivalent to `text/plain`,
  /// both in the [mimeType] argument and in the `data:` URI itself.
  @Since("2.17")
  bool isMimeType(String mimeType) {
    int start = _separatorIndices[0] + 1;
    int end = _separatorIndices[1];
    if (start == end) {
      return mimeType.isEmpty ||
          identical(mimeType, "text/plain") ||
          _caseInsensitiveEquals(mimeType, "text/plain");
    }
    if (mimeType.isEmpty) mimeType = "text/plain";
    return (mimeType.length == end - start) &&
        _caseInsensitiveStartsWith(mimeType, _text, start);
  }

  /// The charset parameter of the media type.
  ///
  /// If the parameters of the media type contains a `charset` parameter
  /// then this returns its value, otherwise it returns `US-ASCII`,
  /// which is the default charset for data URIs.
  /// If the values contain non-ASCII percent escapes, they are decoded as UTF-8.
  ///
  /// If the MIME type representation in the URI text contains URI escapes,
  /// they are unescaped in the returned string.
  String get charset {
    var charsetIndex = _findCharsetIndex();
    if (charsetIndex >= 0) {
      var valueStart = _separatorIndices[charsetIndex + 1] + 1;
      var valueEnd = _separatorIndices[charsetIndex + 2];
      return _Uri._uriDecode(_text, valueStart, valueEnd, utf8, false);
    }
    return "US-ASCII";
  }

  /// Finds the index of the separator before the "charset" parameter.
  ///
  /// Returns the index in [_separatorIndices] of the separator before
  /// the name of the "charset" parameter, or -1 if there is no "charset"
  /// parameter.
  int _findCharsetIndex() {
    var separatorIndices = _separatorIndices;
    // Loop over all MIME-type parameters.
    // Check that the parameter can have two parts (key/value)
    // to ignore a trailing base-64 marker.
    for (int i = 3; i <= separatorIndices.length; i += 2) {
      var keyStart = separatorIndices[i - 2] + 1;
      var keyEnd = separatorIndices[i - 1];
      if (keyEnd == keyStart + "charset".length &&
          _caseInsensitiveStartsWith("charset", _text, keyStart)) {
        return i - 2;
      }
    }
    return -1;
  }

  /// Checks whether the charset parameter of the mime type is [charset].
  ///
  /// If this URI has no "charset" parameter, it is assumed to have a default
  /// of `charset=US-ASCII`.
  /// If [charset] is empty, it's treated like `"US-ASCII"`.
  ///
  /// Returns true if [charset] and the "charset" parameter value are
  /// equal strings, ignoring the case of ASCII letters, or both
  /// correspond to the same [Encoding], as given by [Encoding.getByName].
  @Since("2.17")
  bool isCharset(String charset) {
    var charsetIndex = _findCharsetIndex();
    if (charsetIndex < 0) {
      return charset.isEmpty ||
          _caseInsensitiveEquals(charset, "US-ASCII") ||
          identical(Encoding.getByName(charset), ascii);
    }
    if (charset.isEmpty) charset = "US-ASCII";
    var valueStart = _separatorIndices[charsetIndex + 1] + 1;
    var valueEnd = _separatorIndices[charsetIndex + 2];
    var length = valueEnd - valueStart;
    if (charset.length == length &&
        _caseInsensitiveStartsWith(charset, _text, valueStart)) {
      return true;
    }
    var checkedEncoding = Encoding.getByName(charset);
    return checkedEncoding != null &&
        identical(
          checkedEncoding,
          Encoding.getByName(
            _Uri._uriDecode(_text, valueStart, valueEnd, utf8, false),
          ),
        );
  }

  /// Whether the charset parameter represents [encoding].
  ///
  /// If the "charset" parameter is not present in the URI,
  /// it defaults to "US-ASCII", which is the [ascii] encoding.
  /// If present, it's converted to an [Encoding] using [Encoding.getByName],
  /// and compared to [encoding].
  @Since("2.17")
  bool isEncoding(Encoding encoding) {
    var charsetIndex = _findCharsetIndex();
    if (charsetIndex < 0) {
      return identical(encoding, ascii);
    }
    var valueStart = _separatorIndices[charsetIndex + 1] + 1;
    var valueEnd = _separatorIndices[charsetIndex + 2];
    return identical(
      encoding,
      Encoding.getByName(
        _Uri._uriDecode(_text, valueStart, valueEnd, utf8, false),
      ),
    );
  }

  /// Whether the data is Base64 encoded or not.
  bool get isBase64 => _separatorIndices.length.isOdd;

  /// The content part of the data URI, as its actual representation.
  ///
  /// This string may contain percent escapes.
  String get contentText => _text.substring(_separatorIndices.last + 1);

  /// The content part of the data URI as bytes.
  ///
  /// If the data is Base64 encoded, it will be decoded to bytes.
  ///
  /// If the data is not Base64 encoded, it will be decoded by unescaping
  /// percent-escaped characters and returning byte values of each unescaped
  /// character. The bytes will not be, e.g., UTF-8 decoded.
  Uint8List contentAsBytes() {
    String text = _text;
    int start = _separatorIndices.last + 1;
    if (isBase64) {
      return base64.decoder.convert(text, start);
    }

    // Not base64, do percent-decoding and return the remaining bytes.
    // Compute result size.
    const int percent = 0x25;
    int length = text.length - start;
    for (int i = start; i < text.length; i++) {
      var codeUnit = text.codeUnitAt(i);
      if (codeUnit == percent) {
        i += 2;
        length -= 2;
      }
    }
    // Fill result array.
    Uint8List result = Uint8List(length);
    if (length == text.length) {
      result.setRange(0, length, text.codeUnits, start);
      return result;
    }
    int index = 0;
    for (int i = start; i < text.length; i++) {
      var codeUnit = text.codeUnitAt(i);
      if (codeUnit != percent) {
        result[index++] = codeUnit;
      } else {
        if (i + 2 < text.length) {
          int byte = parseHexByte(text, i + 1);
          if (byte >= 0) {
            result[index++] = byte;
            i += 2;
            continue;
          }
        }
        throw FormatException("Invalid percent escape", text, i);
      }
    }
    assert(index == result.length);
    return result;
  }

  /// Creates a string from the content of the data URI.
  ///
  /// If the content is Base64 encoded, it will be decoded to bytes and then
  /// decoded to a string using [encoding].
  /// If encoding is omitted, the value of a `charset` parameter is used
  /// if it is recognized by [Encoding.getByName]; otherwise it defaults to
  /// the [ascii] encoding, which is the default encoding for data URIs
  /// that do not specify an encoding.
  ///
  /// If the content is not Base64 encoded, it will first have percent-escapes
  /// converted to bytes and then the character codes and byte values are
  /// decoded using [encoding].
  String contentAsString({Encoding? encoding}) {
    if (encoding == null) {
      var charset = this.charset; // Returns "US-ASCII" if not present.
      encoding = Encoding.getByName(charset);
      if (encoding == null) {
        throw UnsupportedError("Unknown charset: $charset");
      }
    }
    String text = _text;
    int start = _separatorIndices.last + 1;
    if (isBase64) {
      var converter = base64.decoder.fuse(encoding.decoder);
      return converter.convert(text.substring(start));
    }
    return _Uri._uriDecode(text, start, text.length, encoding, false);
  }

  /// A map representing the parameters of the media type.
  ///
  /// A data URI may contain parameters between the MIME type and the
  /// data. This converts these parameters to a map from parameter name
  /// to parameter value.
  /// The map only contains parameters that actually occur in the URI.
  /// The `charset` parameter has a default value even if it doesn't occur
  /// in the URI, which is reflected by the [charset] getter. This means that
  /// [charset] may return a value even if `parameters["charset"]` is `null`.
  ///
  /// If the values contain non-ASCII values or percent escapes,
  /// they are decoded as UTF-8.
  Map<String, String> get parameters {
    var result = <String, String>{};
    for (int i = 3; i < _separatorIndices.length; i += 2) {
      var start = _separatorIndices[i - 2] + 1;
      var equals = _separatorIndices[i - 1];
      var end = _separatorIndices[i];
      String key = _Uri._uriDecode(_text, start, equals, utf8, false);
      String value = _Uri._uriDecode(_text, equals + 1, end, utf8, false);
      result[key] = value;
    }
    return result;
  }

  static UriData _parse(String text, int start, Uri? sourceUri) {
    assert(start == 0 || start == 5);
    assert((start == 5) == text.startsWith("data:"));

    /// Character codes.
    const int comma = 0x2c;
    const int slash = 0x2f;
    const int semicolon = 0x3b;
    const int equals = 0x3d;
    List<int> indices = [start - 1];
    int slashIndex = -1;
    var char;
    int i = start;
    for (; i < text.length; i++) {
      char = text.codeUnitAt(i);
      if (char == comma || char == semicolon) break;
      if (char == slash) {
        if (slashIndex < 0) {
          slashIndex = i;
          continue;
        }
        throw FormatException("Invalid MIME type", text, i);
      }
    }
    if (slashIndex < 0 && i > start) {
      // An empty MIME type is allowed, but if non-empty it must contain
      // exactly one slash.
      throw FormatException("Invalid MIME type", text, i);
    }
    while (char != comma) {
      // Parse parameters and/or "base64".
      indices.add(i);
      i++;
      int equalsIndex = -1;
      for (; i < text.length; i++) {
        char = text.codeUnitAt(i);
        if (char == equals) {
          if (equalsIndex < 0) equalsIndex = i;
        } else if (char == semicolon || char == comma) {
          break;
        }
      }
      if (equalsIndex >= 0) {
        indices.add(equalsIndex);
      } else {
        // Have to be final "base64".
        var lastSeparator = indices.last;
        if (char != comma ||
            i != lastSeparator + 7 /* "base64,".length */ ||
            !text.startsWith("base64", lastSeparator + 1)) {
          throw FormatException("Expecting '='", text, i);
        }
        break;
      }
    }
    indices.add(i);
    bool isBase64 = indices.length.isOdd;
    if (isBase64) {
      text = base64.normalize(text, i + 1, text.length);
    } else {
      // Validate "data" part, must only contain RFC 2396 'uric' characters
      // (reserved, unreserved, or escape sequences).
      // Normalize to this (throws on a fragment separator).
      var data = _Uri._normalize(
        text,
        i + 1,
        text.length,
        _uricMask,
        escapeDelimiters: true,
      );
      if (data != null) {
        text = text.replaceRange(i + 1, text.length, data);
      }
    }
    return UriData._(text, indices, sourceUri);
  }

  /// Like [Uri._uriEncode] but takes the input as bytes, not a string.
  ///
  /// Encodes into [buffer] instead of creating its own buffer.
  static void _uriEncodeBytes(
    int canonicalMask,
    List<int> bytes,
    StringSink buffer,
  ) {
    // Encode the string into bytes then generate an ASCII only string
    // by percent encoding selected bytes.
    int byteOr = 0;
    for (int i = 0; i < bytes.length; i++) {
      int byte = bytes[i];
      byteOr |= byte;
      if (byte < 128 &&
          ((_charTables.codeUnitAt(byte) & canonicalMask) != 0)) {
        buffer.writeCharCode(byte);
      } else {
        buffer.writeCharCode(_PERCENT);
        buffer.writeCharCode(_hexDigits.codeUnitAt(byte >> 4));
        buffer.writeCharCode(_hexDigits.codeUnitAt(byte & 0x0f));
      }
    }
    if ((byteOr & ~0xFF) != 0) {
      for (int i = 0; i < bytes.length; i++) {
        var byte = bytes[i];
        if (byte < 0 || byte > 255) {
          throw ArgumentError.value(byte, "non-byte value");
        }
      }
    }
  }

  String toString() =>
      (_separatorIndices[0] == _noScheme) ? "data:$_text" : _text;

}

// --- URI PARSER TABLE --- start --- generated code, do not edit ---
// Use tools/generate_uri_parser_tables.dart to generate this code
// if necessary.

// --------------------------------------------------------------------
// Constants used to read the scanner result.
// The indices points into the table filled by [_scan] which contains
// recognized positions in the scanned URI.
// The `0` index is only used internally.

/// Index of the position of that `:` after a scheme.
const int _schemeEndIndex = 1;

/// Index of the position of the character just before the host name.
const int _hostStartIndex = 2;

/// Index of the position of the `:` before a port value.
const int _portStartIndex = 3;

/// Index of the position of the first character of a path.
const int _pathStartIndex = 4;

/// Index of the position of the `?` before a query.
const int _queryStartIndex = 5;

/// Index of the position of the `#` before a fragment.
const int _fragmentStartIndex = 6;

/// Index of a position where the URI was determined to be "non-simple".
const int _notSimpleIndex = 7;

/// Initial state for scanner.
const int _uriStart = 0;

/// If scanning of a URI terminates in this state or above,
/// consider the URI non-simple
const int _nonSimpleEndStates = 14;

/// Initial state for scheme validation.
const int _schemeStart = 20;

// --------------------------------------------------------------------
/// Transition tables are used to scan a URI to determine its structure.
///
/// The tables represent a state machine with output.
///
/// To scan the URI, start in the [_uriStart] state, then read each character
/// of the URI in order, from start to end, and for each character perform a
/// transition to a new state while writing the current position
/// into the output buffer at a designated index.
///
/// Each state, represented by an integer which is an index into
/// [_scannerTables], has a set of transitions, one for each character.
/// The transitions are encoded as a 5-bit integer representing the next state
/// and a 3-bit index into the output table.
///
/// For URI scanning, only characters in the range U+0020 through U+007E are
/// interesting; all characters outside that range are treated the same.
/// The tables only contain 96 entries, representing the 95 characters in the
/// interesting range, and one entry for all values outside the range.
/// The character entries are stored in one `String` of 96 characters per state,
/// with the transition for a character at position `character ^ 0x60`,
/// which maps the range U+0020 .. U+007F into positions 0 .. 95.
/// All remaining characters are mapped to position 0x1f (`0x7f ^ 0x60`), which
/// represents the transition for all remaining characters.
const String _scannerTables = "\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1\xE1\xE1"
    "\x01\xE1\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1\xE3\xE1\xE1\x01\xE1\x01"
    "\xE1\xCD\x01\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x0E\x03\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x22\x01\xE1\x01\xE1\xAC\xE1\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\xE1\xE1\xE1\x01\xE1\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1"
    "\xEA\xE1\xE1\x01\xE1\x01\xE1\xCD\x01\xE1\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x0A\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x22\x01\xE1\x01\xE1\xAC"
    "\xEB\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B"
    "\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\xEB\xEB\xEB\x8B\xEB\xEB\x8B\x8B\x8B"
    "\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B"
    "\x8B\x8B\x8B\x8B\x8B\xEB\x83\xEB\xEB\x8B\xEB\x8B\xEB\xCD\x8B\xEB\x8B\x8B"
    "\x8B\x8B\x8B\x8B\x8B\x8B\x92\x83\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B\x8B"
    "\xEB\x8B\xEB\x8B\xEB\xAC\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEB\xEB"
    "\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x44\xEB\xEB\x0B\xEB\x0B"
    "\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x12\x44\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC\xE5\x05\x05\x05\x05\x05"
    "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
    "\x05\x05\x05\xE5\xE5\xE5\x05\xE5\x44\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5"
    "\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE8"
    "\x8A\xE5\xE5\x05\xE5\x05\xE5\xCD\x05\xE5\x05\x05\x05\x05\x05\x05\x05\x05"
    "\x05\x8A\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x66\x05\xE5\x05\xE5\xAC"
    "\xE5\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
    "\x05\x05\x05\x05\x05\x05\x05\x05\x05\xE5\xE5\xE5\x05\xE5\x44\xE5\xE5\xE5"
    "\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5\xE5"
    "\xE5\xE5\xE5\xE5\xE5\xE5\x8A\xE5\xE5\x05\xE5\x05\xE5\xCD\x05\xE5\x05\x05"
    "\x05\x05\x05\x05\x05\x05\x05\x8A\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05"
    "\x66\x05\xE5\x05\xE5\xAC\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\x44\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\x8A\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xCD\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\x8A\xE7\x07\x07\x07"
    "\x07\x07\x07\x07\x07\x07\xE7\xE7\xE7\xE7\xE7\xAC\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\x44\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\x8A\xE7\xE7\xE7\xE7\xE7\xE7\xCD\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7\xE7"
    "\xE7\x8A\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\xE7\xE7\xE7\xE7\xE7\xAC"
    "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
    "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
    "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
    "\x08\x08\x08\x08\x08\x08\x08\x05\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
    "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
    "\x08\x08\x08\x08\x08\x08\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEB\xEB"
    "\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEA\xEB\xEB\x0B\xEB\x0B"
    "\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x10\xEA\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC\xEB\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\xEB\xEB\xEB\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB"
    "\xEA\xEB\xEB\x0B\xEB\x0B\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x12\x0A\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC"
    "\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEB\xEB\x0B\xEB\xEB\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\xEB\xEA\xEB\xEB\x0B\xEB\x0B\xEB\xCD\x0B\xEB\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0A\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\xEB\x0B\xEB\x0B\xEB\xAC\xEC\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
    "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\xEC\xEC\xEC"
    "\x0C\xEC\xEC\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
    "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\xEC\xEC\xEC\xEC\x0C\xEC\x0C"
    "\xEC\xCD\x0C\xEC\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\xEC\x0C\x0C\x0C\x0C"
    "\x0C\x0C\x0C\x0C\x0C\x0C\xEC\x0C\xEC\x0C\xEC\x0C\xED\x0D\x0D\x0D\x0D\x0D"
    "\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D"
    "\x0D\x0D\x0D\xED\xED\xED\x0D\xED\xED\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D"
    "\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\xED"
    "\xED\xED\xED\x0D\xED\x0D\xED\xED\x0D\xED\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D"
    "\x0D\xED\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\x0D\xED\x0D\xED\x0D\xED\x0D"
    "\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1\xE1\xE1\x01\xE1\xE1\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\xE1\xEA\xE1\xE1\x01\xE1\x01\xE1\xCD\x01\xE1\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x0F\xEA\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x22\x01\xE1\x01\xE1\xAC\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1\xE1\xE1"
    "\x01\xE1\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xE1\xE9\xE1\xE1\x01\xE1\x01"
    "\xE1\xCD\x01\xE1\x01\x01\x01\x01\x01\x01\x01\x01\x01\x09\x01\x01\x01\x01"
    "\x01\x01\x01\x01\x01\x01\x22\x01\xE1\x01\xE1\xAC\xEB\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\xEB\xEB\xEB\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB"
    "\xEA\xEB\xEB\x0B\xEB\x0B\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x11\xEA\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC"
    "\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEB\xEB\x0B\xEB\xEB\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\xEB\xE9\xEB\xEB\x0B\xEB\x0B\xEB\xCD\x0B\xEB\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x09\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\xEB\x0B\xEB\x0B\xEB\xAC\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEB\xEB"
    "\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\xEA\xEB\xEB\x0B\xEB\x0B"
    "\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x13\xEA\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC\xEB\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\xEB\xEB\xEB\x0B\xEB\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB"
    "\xEA\xEB\xEB\x0B\xEB\x0B\xEB\xCD\x0B\xEB\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
    "\x0B\xEA\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\xEB\x0B\xEB\x0B\xEB\xAC"
    "\xF5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15"
    "\x15\x15\x15\x15\x15\x15\x15\x15\x15\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15"
    "\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5"
    "\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\xF5\x15\xF5\x15\x15\xF5\x15\x15\x15\x15"
    "\x15\x15\x15\x15\x15\x15\xF5\xF5\xF5\xF5\xF5\xF5";

// --------------------------------------------------------------------
/// Scan a string using the [_scannerTables] state machine.
///
/// Scans [uri] from [start] to [end], starting in state [state] and
/// writing output into [indices].
///
/// Returns the final state. If that state is greater than or equal to
/// [_nonSimpleEndStates], the general URI scan should consider the
/// result non-simple, even if no position has been written to
/// [_notSimpleIndex] of [indices].
int _scan(String uri, int start, int end, int state, List<int> indices) {
  // Number of characters in table for each state (range 0x20..0x60).
  const int stateTableSize = 0x60;
  // Value to xor input character with to make valid range start at zero.
  const int _charXor = 96;
  // Limit on valid values after doing xor.
  const int _xorCharLimit = 95;
  // Entry used for invalid input characters (not in the range 0x20-0x7f).
  const int _invalidChar = 0x7F ^ _charXor;
  // Shift to extract write position from transition table entry.
  const int _writeIndexShift = 5;
  // Mask for state part of transition table entry.
  const int _stateMask = 31;

  assert(end <= uri.length);
  for (int i = start; i < end; i++) {
    int char = uri.codeUnitAt(i) ^ _charXor;
    if (char > _xorCharLimit) char = _invalidChar;
    int transition = _scannerTables.codeUnitAt(state * stateTableSize + char);
    state = transition & _stateMask;
    indices[transition >> _writeIndexShift] = i;
  }
  return state;
}
// --- URI PARSER TABLE --- end --- generated code, do not edit ---

final class _SimpleUri implements _PlatformUri {
  final String _uri;
  final int _schemeEnd;
  final int _hostStart;
  final int _portStart;
  final int _pathStart;
  final int _queryStart;
  final int _fragmentStart;

  /// The scheme is often used to distinguish URIs.
  /// To make comparisons more efficient, we cache the value, and
  /// canonicalize a few known types.
  String? _schemeCache;
  int? _hashCodeCache;

  _SimpleUri(
    this._uri,
    this._schemeEnd,
    this._hostStart,
    this._portStart,
    this._pathStart,
    this._queryStart,
    this._fragmentStart,
    this._schemeCache,
  );

  bool get hasScheme => _schemeEnd > 0;
  bool get hasAuthority => _hostStart > 0;
  bool get hasUserInfo => _hostStart > _schemeEnd + 4;
  bool get hasPort => _hostStart > 0 && _portStart + 1 < _pathStart;
  bool get hasQuery => _queryStart < _fragmentStart;
  bool get hasFragment => _fragmentStart < _uri.length;

  bool get _isFile => _schemeEnd == 4 && _uri.startsWith("file");
  bool get _isHttp => _schemeEnd == 4 && _uri.startsWith("http");
  bool get _isHttps => _schemeEnd == 5 && _uri.startsWith("https");
  bool get _isPackage => _schemeEnd == 7 && _uri.startsWith("package");

  /// Like [isScheme] but expects argument to be case normalized.
  bool _isScheme(String scheme) =>
      _schemeEnd == scheme.length && _uri.startsWith(scheme);

  bool get hasAbsolutePath => _uri.startsWith("/", _pathStart);
  bool get hasEmptyPath => _pathStart == _queryStart;

  bool get isAbsolute => hasScheme && !hasFragment;

  bool isScheme(String scheme) {
    if (scheme == null || scheme.isEmpty) return _schemeEnd < 0;
    if (scheme.length != _schemeEnd) return false;
    return _caseInsensitiveStartsWith(scheme, _uri, 0);
  }

  String get scheme {
    return _schemeCache ??= _computeScheme();
  }

  String _computeScheme() {
    if (_schemeEnd <= 0) return "";
    if (_isHttp) return "http";
    if (_isHttps) return "https";
    if (_isFile) return "file";
    if (_isPackage) return "package";
    return _uri.substring(0, _schemeEnd);
  }

  String get authority =>
      _hostStart > 0 ? _uri.substring(_schemeEnd + 3, _pathStart) : "";
  String get userInfo =>
      (_hostStart > _schemeEnd + 3)
          ? _uri.substring(_schemeEnd + 3, _hostStart - 1)
          : "";
  String get host =>
      _hostStart > 0 ? _uri.substring(_hostStart, _portStart) : "";
  int get port {
    if (hasPort) return int.parse(_uri.substring(_portStart + 1, _pathStart));
    if (_isHttp) return 80;
    if (_isHttps) return 443;
    return 0;
  }

  String get path => _uri.substring(_pathStart, _queryStart);
  String get query =>
      (_queryStart < _fragmentStart)
          ? _uri.substring(_queryStart + 1, _fragmentStart)
          : "";
  String get fragment =>
      (_fragmentStart < _uri.length) ? _uri.substring(_fragmentStart + 1) : "";

  String get origin {
    // Check original behavior - W3C spec is wonky!
    bool isHttp = _isHttp;
    if (_schemeEnd < 0) {
      throw StateError("Cannot use origin without a scheme: $this");
    }
    if (!isHttp && !_isHttps) {
      throw StateError(
        "Origin is only applicable to schemes http and https: $this",
      );
    }
    if (_hostStart == _portStart) {
      throw StateError(
        "A $scheme: URI should have a non-empty host name: $this",
      );
    }
    if (_hostStart == _schemeEnd + 3) {
      return _uri.substring(0, _pathStart);
    }
    // Need to drop anon-empty userInfo.
    return _uri.substring(0, _schemeEnd + 3) +
        _uri.substring(_hostStart, _pathStart);
  }

  List<String> get pathSegments {
    int start = _pathStart;
    int end = _queryStart;
    if (_uri.startsWith("/", start)) start++;
    if (start == end) return const <String>[];
    List<String> parts = [];
    for (int i = start; i < end; i++) {
      var char = _uri.codeUnitAt(i);
      if (char == _SLASH) {
        parts.add(_uri.substring(start, i));
        start = i + 1;
      }
    }
    parts.add(_uri.substring(start, end));
    return List<String>.unmodifiable(parts);
  }

  Map<String, String> get queryParameters {
    if (!hasQuery) return const <String, String>{};
    return UnmodifiableMapView<String, String>(Uri.splitQueryString(query));
  }

  Map<String, List<String>> get queryParametersAll {
    if (!hasQuery) return const <String, List<String>>{};
    Map<String, List<String>> queryParameterLists = _Uri._splitQueryStringAll(
      query,
    );
    queryParameterLists.updateAll(_toUnmodifiableStringList);
    return Map<String, List<String>>.unmodifiable(queryParameterLists);
  }

  bool _isPort(String port) {
    int portDigitStart = _portStart + 1;
    return portDigitStart + port.length == _pathStart &&
        _uri.startsWith(port, portDigitStart);
  }

  Uri normalizePath() => this;

  Uri removeFragment() {
    if (!hasFragment) return this;
    return _SimpleUri(
      _uri.substring(0, _fragmentStart),
      _schemeEnd,
      _hostStart,
      _portStart,
      _pathStart,
      _queryStart,
      _fragmentStart,
      _schemeCache,
    );
  }

  Uri replace({
    String? scheme,
    String? userInfo,
    String? host,
    int? port,
    String? path,
    Iterable<String>? pathSegments,
    String? query,
    Map<String, dynamic /*String?|Iterable<String>*/>? queryParameters,
    String? fragment,
  }) {
    bool schemeChanged = false;
    if (scheme != null) {
      scheme = _Uri._makeScheme(scheme, 0, scheme.length);
      schemeChanged = !_isScheme(scheme);
    } else {
      scheme = this.scheme;
    }
    bool isFile = (scheme == "file");
    if (userInfo != null) {
      userInfo = _Uri._makeUserInfo(userInfo, 0, userInfo.length);
    } else if (_hostStart > 0) {
      userInfo = _uri.substring(_schemeEnd + 3, _hostStart);
    } else {
      userInfo = "";
    }
    if (port != null) {
      port = _Uri._makePort(port, scheme);
    } else {
      port = this.hasPort ? this.port : null;
      if (schemeChanged) {
        // The default port might have changed.
        port = _Uri._makePort(port, scheme);
      }
    }
    if (host != null) {
      host = _Uri._makeHost(host, 0, host.length, false);
    } else if (_hostStart > 0) {
      host = _uri.substring(_hostStart, _portStart);
    } else if (userInfo.isNotEmpty || port != null || isFile) {
      host = "";
    }

    bool hasAuthority = host != null;
    if (path != null || pathSegments != null) {
      path = _Uri._makePath(
        path,
        0,
        _stringOrNullLength(path),
        pathSegments,
        scheme,
        hasAuthority,
      );
    } else {
      path = _uri.substring(_pathStart, _queryStart);
      if ((isFile || (hasAuthority && !path.isEmpty)) &&
          !path.startsWith('/')) {
        path = "/" + path;
      }
    }

    if (query != null || queryParameters != null) {
      query = _Uri._makeQuery(
        query,
        0,
        _stringOrNullLength(query),
        queryParameters,
      );
    } else if (_queryStart < _fragmentStart) {
      query = _uri.substring(_queryStart + 1, _fragmentStart);
    }

    if (fragment != null) {
      fragment = _Uri._makeFragment(fragment, 0, fragment.length);
    } else if (_fragmentStart < _uri.length) {
      fragment = _uri.substring(_fragmentStart + 1);
    }

    return _Uri._internal(scheme, userInfo, host, port, path, query, fragment);
  }

  Uri resolve(String reference) {
    return resolveUri(Uri.parse(reference));
  }

  Uri resolveUri(Uri reference) {
    if (reference is _SimpleUri) {
      return _simpleMerge(this, reference);
    }
    return _toNonSimple().resolveUri(reference);
  }

  // Returns the index of the `/` after the package name of a package URI.
  //
  // Returns negative if the URI is not a valid package URI:
  // * Scheme must be "package".
  // * No authority.
  // * Path starts with "something"/
  // * where "something" is not all "." characters,
  // * and contains no escapes or colons.
  //
  // The characters are necessarily valid path characters.
  static int _packageNameEnd(_SimpleUri uri) {
    if (uri._isPackage && !uri.hasAuthority) {
      // Becomes Non zero if seeing any non-dot character.
      // Also guards against empty package names.
      return _skipPackageNameChars(uri._uri, uri._pathStart, uri._queryStart);
    }
    return -1;
  }

  // Merge two simple URIs. This should always result in a prefix of
  // one concatenated with a suffix of the other, possibly with a `/` in
  // the middle of two merged paths, which is again simple.
  // In a few cases, there might be a need for extra normalization, when
  // resolving on top of a known scheme.
  Uri _simpleMerge(_SimpleUri base, _SimpleUri ref) {
    if (ref.hasScheme) return ref;
    if (ref.hasAuthority) {
      if (!base.hasScheme) return ref;
      bool isSimple = true;
      if (base._isFile) {
        isSimple = !ref.hasEmptyPath;
      } else if (base._isHttp) {
        isSimple = !ref._isPort("80");
      } else if (base._isHttps) {
        isSimple = !ref._isPort("443");
      }
      if (isSimple) {
        var delta = base._schemeEnd + 1;
        var newUri =
            base._uri.substring(0, base._schemeEnd + 1) +
            ref._uri.substring(ref._schemeEnd + 1);
        return _SimpleUri(
          newUri,
          base._schemeEnd,
          ref._hostStart + delta,
          ref._portStart + delta,
          ref._pathStart + delta,
          ref._queryStart + delta,
          ref._fragmentStart + delta,
          base._schemeCache,
        );
      } else {
        // This will require normalization, so use the _Uri implementation.
        return _toNonSimple().resolveUri(ref);
      }
    }
    if (ref.hasEmptyPath) {
      if (ref.hasQuery) {
        int delta = base._queryStart - ref._queryStart;
        var newUri =
            base._uri.substring(0, base._queryStart) +
            ref._uri.substring(ref._queryStart);
        return _SimpleUri(
          newUri,
          base._schemeEnd,
          base._hostStart,
          base._portStart,
          base._pathStart,
          ref._queryStart + delta,
          ref._fragmentStart + delta,
          base._schemeCache,
        );
      }
      if (ref.hasFragment) {
        int delta = base._fragmentStart - ref._fragmentStart;
        var newUri =
            base._uri.substring(0, base._fragmentStart) +
            ref._uri.substring(ref._fragmentStart);
        return _SimpleUri(
          newUri,
          base._schemeEnd,
          base._hostStart,
          base._portStart,
          base._pathStart,
          base._queryStart,
          ref._fragmentStart + delta,
          base._schemeCache,
        );
      }
      return base.removeFragment();
    }
    if (ref.hasAbsolutePath) {
      int basePathStart = base._pathStart;
      int packageNameEnd = _packageNameEnd(this);
      if (packageNameEnd > 0) basePathStart = packageNameEnd;
      var delta = basePathStart - ref._pathStart;
      var newUri =
          base._uri.substring(0, basePathStart) +
          ref._uri.substring(ref._pathStart);
      return _SimpleUri(
        newUri,
        base._schemeEnd,
        base._hostStart,
        base._portStart,
        base._pathStart,
        ref._queryStart + delta,
        ref._fragmentStart + delta,
        base._schemeCache,
      );
    }
    if (base.hasEmptyPath && base.hasAuthority) {
      // ref has relative non-empty path.
      // Add a "/" in front, then leading "/../" segments are folded to "/".
      int refStart = ref._pathStart;
      while (ref._uri.startsWith("../", refStart)) {
        refStart += 3;
      }
      var delta = base._pathStart - refStart + 1;
      var newUri =
          "${base._uri.substring(0, base._pathStart)}/"
          "${ref._uri.substring(refStart)}";
      return _SimpleUri(
        newUri,
        base._schemeEnd,
        base._hostStart,
        base._portStart,
        base._pathStart,
        ref._queryStart + delta,
        ref._fragmentStart + delta,
        base._schemeCache,
      );
    }
    // Merge paths.

    // The RFC 3986 algorithm merges the base path without its final segment
    // (anything after the final "/", or everything if the base path doesn't
    // contain any "/"), and the reference path.
    // Then it removes "." and ".." segments using the remove-dot-segment
    // algorithm.
    // This code combines the two steps. It is simplified by knowing that
    // the base path contains no "." or ".." segments, and the reference
    // path can only contain leading ".." segments.

    String baseUri = base._uri;
    String refUri = ref._uri;
    int baseStart = base._pathStart;
    int baseEnd = base._queryStart;
    int packageNameEnd = _packageNameEnd(this);
    if (packageNameEnd >= 0) {
      baseStart = packageNameEnd; // At the `/` after the first package name.
    } else {
      while (baseUri.startsWith("../", baseStart)) baseStart += 3;
    }
    int refStart = ref._pathStart;
    int refEnd = ref._queryStart;

    /// Count of leading ".." segments in reference path.
    /// The count is decremented when the segment is matched with a
    /// segment of the base path, and both are then omitted from the result.
    int backCount = 0;

    /// Count "../" segments and advance `refStart` to after the segments.
    while (refStart + 3 <= refEnd && refUri.startsWith("../", refStart)) {
      refStart += 3;
      backCount += 1;
    }

    // Extra slash inserted between base and reference path parts if
    // the base path contains any slashes, or empty string if none.
    // (We could use a slash from the base path in most cases, but not if
    // we remove the entire base path).
    String insert = "";

    /// Remove segments from the base path.
    /// Start with the segment trailing the last slash,
    /// then remove segments for each leading "../" segment
    /// from the reference path, or as many of them as are available.
    while (baseEnd > baseStart) {
      baseEnd--;
      int char = baseUri.codeUnitAt(baseEnd);
      if (char == _SLASH) {
        insert = "/";
        if (backCount == 0) break;
        backCount--;
      }
    }

    if (baseEnd == baseStart && !base.hasScheme && !base.hasAbsolutePath) {
      // If the base is *just* a relative path (no scheme or authority),
      // then merging with another relative path doesn't follow the
      // RFC-3986 behavior.
      // Don't need to check `base.hasAuthority` since the base path is
      // non-empty - if there is an authority, a non-empty path is absolute.

      // We reached the start of the base path, and want to stay relative,
      // so don't insert a slash.
      insert = "";
      // If we reached the start of the base path with more "../" left over
      // in the reference path, include those segments in the result.
      refStart -= backCount * 3;
    }

    var delta = baseEnd - refStart + insert.length;
    var newUri =
        "${base._uri.substring(0, baseEnd)}$insert"
        "${ref._uri.substring(refStart)}";

    return _SimpleUri(
      newUri,
      base._schemeEnd,
      base._hostStart,
      base._portStart,
      base._pathStart,
      ref._queryStart + delta,
      ref._fragmentStart + delta,
      base._schemeCache,
    );
  }

  String toFilePath({bool? windows}) {
    if (_schemeEnd >= 0 && !_isFile) {
      throw UnsupportedError("Cannot extract a file path from a $scheme URI");
    }
    if (_queryStart < _uri.length) {
      if (_queryStart < _fragmentStart) {
        throw UnsupportedError(
          "Cannot extract a file path from a URI with a query component",
        );
      }
      throw UnsupportedError(
        "Cannot extract a file path from a URI with a fragment component",
      );
    }
    return (windows ?? _Uri._isWindows)
        ? _Uri._toWindowsFilePath(this)
        : _toFilePath();
  }

  String _toFilePath() {
    if (_hostStart < _portStart) {
      // Has authority and non-empty host.
      throw UnsupportedError(
        "Cannot extract a non-Windows file path from a file URI "
        "with an authority",
      );
    }
    return this.path;
  }

  UriData? get data {
    assert(scheme != "data");
    return null;
  }

  int get hashCode => _hashCodeCache ??= _uri.hashCode;

  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is Uri && _uri == other.toString();
  }

  Uri _toNonSimple() {
    return _Uri._internal(
      this.scheme,
      this.userInfo,
      this.hasAuthority ? this.host : null,
      this.hasPort ? this.port : null,
      this.path,
      this.hasQuery ? this.query : null,
      this.hasFragment ? this.fragment : null,
    );
  }

  String toString() => _uri;
}

/// Special [_Uri] created from an existing [UriData].
class _DataUri extends _Uri {
  final UriData _data;

  _DataUri(this._data, String path, String? query)
    : super._internal("data", "", null, null, path, query, null);

  UriData? get data => _data;
}

/// Checks whether [text] starts with "data:" at position [start].
///
/// The text must be long enough to allow reading five characters
/// from the [start] position.
///
/// Returns an integer value which is zero if text starts with all-lowercase
/// "data:" and 0x20 if the text starts with "data:" that isn't all lower-case.
/// All other values means the text starts with some other character.
int _startsWithData(String text, int start) {
  // Multiply by 3 to avoid a non-colon character making delta be 0x20.
  int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
  delta |= text.codeUnitAt(start) ^ 0x64 /*d*/;
  delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
  delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
  delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
  return delta;
}

/// Helper function returning the length of a string, or `0` for `null`.
int _stringOrNullLength(String? s) => (s == null) ? 0 : s.length;

List<String> _toUnmodifiableStringList(String key, List<String> list) =>
    List<String>.unmodifiable(list);

/// Counts valid package name characters in [source].
///
/// If [source] starts at [start] with a valid package name,
/// followed by a `/`, no later than [end],
/// then the position of the `/` is returned.
/// If not, a negative value is returned.
/// (Assumes source characters are valid path characters.)
/// A name only consisting of `.` characters is not a valid
/// package name.
int _skipPackageNameChars(String source, int start, int end) {
  // Becomes non-zero when seeing a non-dot character.
  // Also guards against empty package names.
  var dots = 0;
  for (var i = start; i < end; i++) {
    var char = source.codeUnitAt(i);
    if (char == _SLASH) return (dots != 0) ? i : -1;
    if (char == _PERCENT || char == _COLON) return -1;
    dots |= char ^ _DOT;
  }
  return -1;
}

/// Whether [string] at [start] starts with  [prefix], ignoring case.
///
/// Returns whether [string] at offset [start]
/// starts with the characters of [prefix],
/// but ignores differences in the cases of ASCII letters,
/// so `a` and `A` are considered equal.
///
/// The [string] must be at least as long as [prefix].
///
/// When used to checks the schemes of URIs,
/// this function doesn't check that the characters are valid URI scheme
/// characters. The [string] is assumed to be a valid URI,
/// so if [prefix] matches it, it has to be valid too.
bool _caseInsensitiveStartsWith(String prefix, String string, int start) =>
    _caseInsensitiveCompareStart(prefix, string, start) >= 0;

/// Compares [string] at [start] with [prefix], ignoring case.
///
/// Returns 0 if [string] starts with [prefix] at offset [start].
/// Returns 0x20 if [string] starts with [prefix] at offset [start],
/// but some ASCII letters have different case.
/// Returns a negative value if [string] does not start with [prefix],
/// at offset [start] even ignoring case differences.
///
/// The [string] must be at least as long as `start + prefix.length`.
int _caseInsensitiveCompareStart(String prefix, String string, int start) {
  int result = 0;
  for (int i = 0; i < prefix.length; i++) {
    int prefixChar = prefix.codeUnitAt(i);
    int stringChar = string.codeUnitAt(start + i);
    int delta = prefixChar ^ stringChar;
    if (delta != 0) {
      if (delta == 0x20) {
        // Might be a case difference.
        int lowerChar = stringChar | delta;
        if (0x61 /*a*/ <= lowerChar && lowerChar <= 0x7a /*z*/ ) {
          result = 0x20;
          continue;
        }
      }
      return -1;
    }
  }
  return result;
}

/// Checks whether two strings are equal ignoring case differences.
///
/// Returns whether if [string1] and [string2] has the same length
/// and same characters, but ignores the cases of ASCII letters,
/// so `a` and `A` are considered equal.
bool _caseInsensitiveEquals(String string1, String string2) =>
    string1.length == string2.length &&
    _caseInsensitiveStartsWith(string1, string2, 0);


// --- URI CHARSET TABLE --- start --- generated code, do not edit ---
// Use tools/generate_uri_parser_tables.dart to generate this code
// if necessary.

// The unreserved characters of RFC 3986.
// [A-Za-z0-9\-._~]
const _unreservedMask = 0x0001;

// The unreserved characters of RFC 2396.
// [A-Za-z0-9!'()*\-._~]
const _unreserved2396Mask = 0x0002;

// Table of reserved characters specified by ECMAScript 5.
// [A-Za-z0-9!#$&'()*+,\-./:;=?_~]
const _encodeFullMask = 0x0004;

// Characters allowed in the scheme.
// [A-Za-z0-9+\-.]
const _schemeMask = 0x0008;

// Characters allowed in the userinfo as of RFC 3986.
// RFC 3986 Appendix A
// userinfo = *( unreserved / pct-encoded / sub-delims / ':')
// [A-Za-z0-9!$&'()*+,\-.:;=_~] (without '%')
const _userinfoMask = 0x0010;

// Characters allowed in the reg-name as of RFC 3986.
// RFC 3986 Appendix A
// reg-name = *( unreserved / pct-encoded / sub-delims )
// Same as `_userInfoMask` without the `:`.
// // [A-Za-z0-9!$%&'()*+,\-.;=_~] (including '%')
const _regNameMask = 0x0020;

// Characters allowed in the path as of RFC 3986.
// RFC 3986 section 3.3.
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
// [A-Za-z0-9!$&'()*+,\-.:;=@_~] (without '%')
const _pathCharMask = 0x0040;

// Characters allowed in the path as of RFC 3986.
// RFC 3986 section 3.3 *and* slash.
// [A-Za-z0-9!$&'()*+,\-./:;=@_~] (without '%')
const _pathCharOrSlashMask = 0x0080;

// Characters allowed in the query as of RFC 3986.
// RFC 3986 section 3.4.
// query = *( pchar / "/" / "?" )
// [A-Za-z0-9!$&'()*+,\-./:;=?@_~] (without '%')
const _queryCharMask = 0x0100;

// Characters allowed in the ZoneID as of RFC 6874.
// ZoneID = 1*( unreserved / pct-encoded )
// [A-Za-z0-9\-._~] + '%'
const _zoneIDMask = _unreservedMask;

// Table of the `token` characters of RFC 2045 in a `data:` URI.
//
// A token is any US-ASCII character except SPACE, control characters and
// `tspecial` characters. The `tspecial` category is:
// '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[, ']', '?', '='.
//
// In a data URI, we also need to escape '%' and '#' characters.
const _tokenCharMask = 0x0200;

// All non-escape RFC-2396 "uric" characters.
//
// The "uric" character set is defined by:
// ```
//  uric        =  reserved | unreserved | escaped
//  reserved    =  ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
//  unreserved  =  alphanum | mark
//  mark        =  "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
// ```
// This is the same characters as in a URI query (which is URI pchar plus '?')
const _uricMask = _queryCharMask;

// General delimiter characters, RFC 3986 section 2.2.
// gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
// [:/?#[]@]
const _genDelimitersMask = 0x0400;

const String _charTables = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\u03f6\x00\u0404\u03f4\x20\u03f4\u03f6\u01f6\u01f6\u03f6\u03fc"
    "\u01f4\u03ff\u03ff\u0584\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff"
    "\u03ff\u03ff\u05d4\u01f4\x00\u01f4\x00\u0504\u05c4\u03ff\u03ff\u03ff\u03ff"
    "\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff"
    "\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0400\x00"
    "\u0400\u0200\u03f7\u0200\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff"
    "\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff"
    "\u03ff\u03ff\u03ff\u03ff\u03ff\u03ff\u0200\u0200\u0200\u03f7\x00";
// --- URI CHARSET TABLE --- end --- generated code, do not edit ---
