content: // Copyright 2019 Google Inc. Use of this source code is governed by an
  // MIT-style license that can be found in the LICENSE file or at
  // https://opensource.org/licenses/MIT.
  
  import 'package:source_span/source_span.dart';
  
  import 'ast/css.dart';
  import 'ast/node.dart';
  import 'callable.dart';
  import 'extend/extension_store.dart';
  import 'value.dart';
  
  /// The interface for a Sass module.
  abstract interface class Module<T extends AsyncCallable> {
    /// The canonical URL for this module's source file.
    ///
    /// This may be `null` if the module was loaded from a string without a URL
    /// provided.
    Uri? get url;
  
    /// Modules that this module uses.
    List<Module<T>> get upstream;
  
    /// The module's variables.
    Map<String, Value> get variables;
  
    /// The nodes where each variable in [_variables] was defined.
    ///
    /// This stores [AstNode]s rather than [FileSpan]s so it can avoid calling
    /// [AstNode.span] if the span isn't required, since some nodes need to do
    /// real work to manufacture a source span.
    ///
    /// Implementations must ensure that this has the same keys as [variables].
    Map<String, AstNode> get variableNodes;
  
    /// The module's functions.
    ///
    /// Implementations must ensure that each [AsyncCallable] is stored under its
    /// own name.
    Map<String, T> get functions;
  
    /// The module's mixins.
    ///
    /// Implementations must ensure that each [AsyncCallable] is stored under its
    /// own name.
    Map<String, T> get mixins;
  
    /// The extensions defined in this module, which is also able to update
    /// [css]'s style rules in-place based on downstream extensions.
    ExtensionStore get extensionStore;
  
    /// The module's CSS tree.
    CssStylesheet get css;
  
    /// A map from modules in [upstream] to loud comments written in this module
    /// that should be emitted before the given module.
    Map<Module<T>, List<CssComment>> get preModuleComments;
  
    /// Whether this module *or* any modules in [upstream] contain any CSS.
    bool get transitivelyContainsCss;
  
    /// Whether this module *or* any modules in [upstream] contain `@extend`
    /// rules.
    bool get transitivelyContainsExtensions;
  
    /// Sets the variable named [name] to [value], associated with
    /// [nodeWithSpan]'s source span.
    ///
    /// This takes an [AstNode] rather than a [FileSpan] so it can avoid calling
    /// [AstNode.span] if the span isn't required, since some nodes need to do
    /// real work to manufacture a source span.
    ///
    /// Throws a [SassScriptException] if this module doesn't define a variable
    /// named [name].
    void setVariable(String name, Value value, AstNode nodeWithSpan);
  
    /// Returns an opaque object that will be equal to another
    /// `variableIdentity()` return value for the same name in another module if
    /// and only if both modules expose identical definitions of the variable in
    /// question, as defined by the Sass spec.
    Object variableIdentity(String name);
  
    /// Whether this module exposes any variables from among [variables] that
    /// could have been configured when the module was loaded.
    bool couldHaveBeenConfigured(Set<String> variables);
  
    /// Creates a copy of this module with new [css] and [extender].
    Module<T> cloneCss();
  }
  