// Copyright (c) 2017, 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.

import 'allocator.dart';
import 'base.dart';
import 'specs/class.dart';
import 'specs/code.dart';
import 'specs/constructor.dart';
import 'specs/directive.dart';
import 'specs/enum.dart';
import 'specs/expression.dart';
import 'specs/extension.dart';
import 'specs/extension_type.dart';
import 'specs/field.dart';
import 'specs/library.dart';
import 'specs/method.dart';
import 'specs/mixin.dart';
import 'specs/reference.dart';
import 'specs/type_function.dart';
import 'specs/type_record.dart';
import 'specs/type_reference.dart';
import 'specs/typedef.dart';
import 'visitors.dart';

/// Helper method improving on [StringSink.writeAll].
///
/// For every `Spec` in [elements], executing [visit].
///
/// If [elements] is at least 2 elements, inserts [separator] delimiting them.
StringSink visitAll<T>(
  Iterable<T> elements,
  StringSink output,
  void Function(T) visit, [
  String separator = ', ',
]) {
  // Basically, this whole method is an improvement on
  //   output.writeAll(specs.map((s) => s.accept(visitor));
  //
  // ... which would allocate more StringBuffer(s) for a one-time use.
  if (elements.isEmpty) {
    return output;
  }
  final iterator = elements.iterator..moveNext();
  visit(iterator.current);
  while (iterator.moveNext()) {
    output.write(separator);
    visit(iterator.current);
  }
  return output;
}

class DartEmitter extends Object
    with CodeEmitter, ExpressionEmitter
    implements SpecVisitor<StringSink> {
  @override
  final Allocator allocator;

  /// If directives should be ordered while emitting.
  ///
  /// Ordering rules follow the guidance in
  /// [Effective Dart](https://dart.dev/guides/language/effective-dart/style#ordering)
  /// and the
  /// [directives_ordering](https://dart-lang.github.io/linter/lints/directives_ordering.html)
  /// lint.
  final bool orderDirectives;

  /// If nullable types should be emitted with the nullable suffix ("?").
  ///
  /// Null safety syntax should only be enabled if the output will be used with
  /// a Dart language version which supports it.
  final bool _useNullSafetySyntax;

  /// Creates a new instance of [DartEmitter].
  ///
  /// May specify an [Allocator] to use for references and imports,
  /// otherwise uses [Allocator.none] which never prefixes references and will
  /// not automatically emit import directives.
  DartEmitter({
    this.allocator = Allocator.none,
    this.orderDirectives = false,
    bool useNullSafetySyntax = false,
  }) : _useNullSafetySyntax = useNullSafetySyntax;

  /// Creates a new instance of [DartEmitter] with simple automatic imports.
  factory DartEmitter.scoped({
    bool orderDirectives = false,
    bool useNullSafetySyntax = false,
  }) => DartEmitter(
    allocator: Allocator.simplePrefixing(),
    orderDirectives: orderDirectives,
    useNullSafetySyntax: useNullSafetySyntax,
  );

  static bool _isLambdaBody(Code? code) =>
      code is ToCodeExpression && !code.isStatement;

  /// Whether the provided [method] is considered a lambda method.
  static bool _isLambdaMethod(Method method) =>
      method.lambda ?? _isLambdaBody(method.body);

  /// Whether the provided [constructor] is considered a lambda method.
  static bool _isLambdaConstructor(Constructor constructor) =>
      constructor.lambda ??
      constructor.factory && _isLambdaBody(constructor.body);

  @override
  StringSink visitAnnotation(Expression spec, [StringSink? output]) {
    (output ??= StringBuffer()).write('@');
    spec.accept(this, output);
    output.write(' ');
    return output;
  }

  @override
  StringSink visitClass(Class spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    void writeModifier() {
      if (spec.modifier != null) {
        out.write('${spec.modifier!.name} ');
      }
    }

    if (spec.sealed) {
      out.write('sealed ');
    } else {
      if (spec.abstract) {
        out.write('abstract ');
      }
      writeModifier();
      if (spec.mixin) {
        out.write('mixin ');
      }
    }
    out.write('class ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.extend != null) {
      out.write(' extends ');
      spec.extend!.type.accept(this, out);
    }
    if (spec.mixins.isNotEmpty) {
      out
        ..write(' with ')
        ..writeAll(
          spec.mixins.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    out.write(' {');
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln(' }');
    return out;
  }

  @override
  StringSink visitMixin(Mixin spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    if (spec.base) {
      out.write('base ');
    }
    out.write('mixin ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.on != null) {
      out.write(' on ');
      spec.on!.type.accept(this, out);
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }
    out.write('  {');
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.write('  }');
    return out;
  }

  @override
  StringSink visitConstructor(
    Constructor spec,
    String clazz, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.constant) {
      output.write('const ');
    }
    if (spec.factory) {
      output.write('factory ');
    }
    output.write(clazz);
    if (spec.name != null) {
      output
        ..write('.')
        ..write(spec.name);
    }
    output.write('(');
    final hasMultipleParameters =
        spec.requiredParameters.length + spec.optionalParameters.length > 1;
    if (spec.requiredParameters.isNotEmpty) {
      var count = 0;
      for (final p in spec.requiredParameters) {
        count++;
        _visitParameter(p, output);
        if (hasMultipleParameters ||
            spec.requiredParameters.length != count ||
            spec.optionalParameters.isNotEmpty) {
          output.write(', ');
        }
      }
    }
    if (spec.optionalParameters.isNotEmpty) {
      final named = spec.optionalParameters.any((p) => p.named);
      if (named) {
        output.write('{');
      } else {
        output.write('[');
      }
      var count = 0;
      for (final p in spec.optionalParameters) {
        count++;
        _visitParameter(p, output, optional: true, named: named);
        if (hasMultipleParameters || spec.optionalParameters.length != count) {
          output.write(', ');
        }
      }
      if (named) {
        output.write('}');
      } else {
        output.write(']');
      }
    }
    output.write(')');
    if (spec.initializers.isNotEmpty) {
      output.write(' : ');
      var count = 0;
      for (final initializer in spec.initializers) {
        count++;
        initializer.accept(this, output);
        if (count != spec.initializers.length) {
          output.write(', ');
        }
      }
    }
    if (spec.redirect != null) {
      output.write(' = ');
      spec.redirect!.type.accept(this, output);
      output.write(';');
    } else if (spec.body != null) {
      if (_isLambdaConstructor(spec)) {
        output.write(' => ');
        spec.body!.accept(this, output);
        output.write(';');
      } else {
        output.write(' { ');
        spec.body!.accept(this, output);
        output.write(' }');
      }
    } else {
      output.write(';');
    }
    output.writeln();
    return output;
  }

  @override
  StringSink visitExtension(Extension spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    out.write('extension');
    if (spec.name != null) {
      out.write(' ${spec.name}');
    }
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.on != null) {
      out.write(' on ');
      spec.on!.type.accept(this, out);
    }
    out.write(' {');
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln(' }');
    return out;
  }

  @override
  StringSink visitExtensionType(ExtensionType spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }

    out.write('extension type ');
    if (spec.constant) out.write('const ');
    out.write(spec.name);
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.primaryConstructorName.isNotEmpty) {
      out.write('.${spec.primaryConstructorName}');
    }
    out.write('(');
    _visitRepresentationDeclaration(spec.representationDeclaration, out);
    out.write(')');

    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ',',
        );
    }

    out.writeln(' {');
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln('}');
    return out;
  }

  void _visitRepresentationDeclaration(
    RepresentationDeclaration spec,
    StringSink out,
  ) {
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    spec.declaredRepresentationType.accept(this, out);
    out.write(' ${spec.name}');
  }

  @override
  StringSink visitDirective(Directive spec, [StringSink? output]) {
    output ??= StringBuffer();
    switch (spec.type) {
      case DirectiveType.import:
        output.write('import ');
        break;
      case DirectiveType.export:
        output.write('export ');
        break;
      case DirectiveType.part:
        output.write('part ');
        break;
      case DirectiveType.partOf:
        output.write('part of ');
        break;
    }
    output.write("'${spec.url}'");
    if (spec.as != null) {
      if (spec.deferred) {
        output.write(' deferred ');
      }
      output.write(' as ${spec.as}');
    }
    if (spec.show.isNotEmpty) {
      output
        ..write(' show ')
        ..writeAll(spec.show, ', ');
    } else if (spec.hide.isNotEmpty) {
      output
        ..write(' hide ')
        ..writeAll(spec.hide, ', ');
    }
    output.write(';');
    return output;
  }

  @override
  StringSink visitField(Field spec, [StringSink? output]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.static) {
      output.write('static ');
    }
    if (spec.late && _useNullSafetySyntax) {
      output.write('late ');
    }
    switch (spec.modifier) {
      case FieldModifier.var$:
        if (spec.type == null) {
          output.write('var ');
        }
        break;
      case FieldModifier.final$:
        output.write('final ');
        break;
      case FieldModifier.constant:
        output.write('const ');
        break;
    }
    if (spec.type != null) {
      spec.type!.type.accept(this, output);
      output.write(' ');
    }
    output.write(spec.name);
    if (spec.assignment != null) {
      output.write(' = ');
      startConstCode(spec.modifier == FieldModifier.constant, () {
        spec.assignment!.accept(this, output);
      });
    }
    output.writeln(';');
    return output;
  }

  @override
  StringSink visitLibrary(Library spec, [StringSink? output]) {
    output ??= StringBuffer();

    if (spec.comments.isNotEmpty) {
      spec.comments.map((line) => '// $line').forEach(output.writeln);
      output.writeln();
    }

    if (spec.generatedByComment != null) {
      output
        ..writeln('// ${spec.generatedByComment}')
        ..writeln();
    }

    if (spec.ignoreForFile.isNotEmpty) {
      final ignores = spec.ignoreForFile.toList()..sort();
      final lines = ['// ignore_for_file: ${ignores.first}'];
      for (var ignore in ignores.skip(1)) {
        if (lines.last.length + 2 + ignore.length > 80) {
          lines.add('// ignore_for_file: $ignore');
        } else {
          lines[lines.length - 1] = '${lines.last}, $ignore';
        }
      }
      lines.forEach(output.writeln);
      output.writeln();
    }

    // Process the body first in order to prime the allocators.
    final body = StringBuffer();
    for (final spec in spec.body) {
      spec.accept(this, body);
      if (spec is Method && _isLambdaMethod(spec)) {
        body.write(';');
      }
    }

    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.name != null) {
      output.write('library ${spec.name!};');
    } else if (spec.annotations.isNotEmpty || spec.docs.isNotEmpty) {
      // An explicit _unnamed_ library directive is only required if there are
      // annotations or doc comments on the library.
      output.write('library;');
    }

    final directives = <Directive>[...allocator.imports, ...spec.directives];

    if (orderDirectives) {
      directives.sort();
    }

    Directive? previous;
    if (directives.any((d) => d.as?.startsWith('_') ?? false)) {
      output.writeln(
        '// ignore_for_file: no_leading_underscores_for_library_prefixes',
      );
    }
    for (final directive in directives) {
      if (_newLineBetween(orderDirectives, previous, directive)) {
        // Note: dartfmt handles creating new lines between directives.
        // 2 lines are written here. The first one comes after the previous
        // directive `;`, the second is the empty line.
        output
          ..writeln()
          ..writeln();
      }
      directive.accept(this, output);
      previous = directive;
    }
    output.write(body);
    return output;
  }

  @override
  StringSink visitFunctionType(FunctionType spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    if (spec.returnType != null) {
      spec.returnType!.accept(this, out);
      out.write(' ');
    }
    out.write('Function');
    if (spec.types.isNotEmpty) {
      out.write('<');
      visitAll<Reference>(spec.types, out, (spec) {
        spec.accept(this, out);
      });
      out.write('>');
    }
    out.write('(');
    final needsTrailingComma =
        spec.requiredParameters.length +
            spec.optionalParameters.length +
            spec.namedRequiredParameters.length +
            spec.namedParameters.length >
        1;
    visitAll<Reference>(spec.requiredParameters, out, (spec) {
      spec.accept(this, out);
    });
    final hasNamedParameters =
        spec.namedRequiredParameters.isNotEmpty ||
        spec.namedParameters.isNotEmpty;
    if (spec.requiredParameters.isNotEmpty &&
        (needsTrailingComma ||
            spec.optionalParameters.isNotEmpty ||
            hasNamedParameters)) {
      out.write(', ');
    }
    if (spec.optionalParameters.isNotEmpty) {
      out.write('[');
      visitAll<Reference>(spec.optionalParameters, out, (spec) {
        spec.accept(this, out);
      });
      if (needsTrailingComma) {
        out.write(', ');
      }
      out.write(']');
    } else if (hasNamedParameters) {
      out.write('{');
      visitAll<String>(spec.namedRequiredParameters.keys, out, (name) {
        out.write('required ');
        spec.namedRequiredParameters[name]!.accept(this, out);
        out
          ..write(' ')
          ..write(name);
      });
      if (spec.namedRequiredParameters.isNotEmpty &&
          spec.namedParameters.isNotEmpty) {
        out.write(', ');
      }
      visitAll<String>(spec.namedParameters.keys, out, (name) {
        spec.namedParameters[name]!.accept(this, out);
        out
          ..write(' ')
          ..write(name);
      });
      if (needsTrailingComma) {
        out.write(', ');
      }
      out.write('}');
    }
    out.write(')');
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      out.write('?');
    }
    return out;
  }

  @override
  StringSink visitRecordType(RecordType spec, [StringSink? output]) {
    final out = (output ??= StringBuffer())..write('(');
    visitAll<Reference>(spec.positionalFieldTypes, out, (spec) {
      spec.accept(this, out);
    });
    if (spec.namedFieldTypes.isNotEmpty) {
      if (spec.positionalFieldTypes.isNotEmpty) {
        out.write(', ');
      }
      out.write('{');
      visitAll<MapEntry<String, Reference>>(spec.namedFieldTypes.entries, out, (
        entry,
      ) {
        entry.value.accept(this, out);
        out.write(' ${entry.key}');
      });
      out.write('}');
    } else if (spec.positionalFieldTypes.length == 1) {
      out.write(',');
    }
    out.write(')');
    // It doesn't really make sense to use records without
    // `_useNullSafetySyntax`, but since code_builder is generally very
    // permissive, follow it here too.
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      out.write('?');
    }
    return out;
  }

  @override
  StringSink visitTypeDef(TypeDef spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    out.write('typedef ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    out.write(' = ');
    spec.definition.accept(this, out);
    out.writeln(';');
    return out;
  }

  @override
  StringSink visitMethod(Method spec, [StringSink? output]) {
    output ??= StringBuffer();
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    if (spec.external) {
      output.write('external ');
    }
    if (spec.static) {
      output.write('static ');
    }
    if (spec.returns != null) {
      spec.returns!.accept(this, output);
      output.write(' ');
    }
    if (spec.type == MethodType.getter) {
      output
        ..write('get ')
        ..write(spec.name);
    } else {
      if (spec.type == MethodType.setter) {
        output.write('set ');
      }
      if (spec.name != null) {
        output.write(spec.name);
      }
      visitTypeParameters(spec.types.map((r) => r.type), output);
      output.write('(');
      final hasMultipleParameters =
          spec.requiredParameters.length + spec.optionalParameters.length > 1;
      if (spec.requiredParameters.isNotEmpty) {
        var count = 0;
        for (final p in spec.requiredParameters) {
          count++;
          _visitParameter(p, output);
          if (hasMultipleParameters ||
              spec.requiredParameters.length != count ||
              spec.optionalParameters.isNotEmpty) {
            output.write(', ');
          }
        }
      }
      if (spec.optionalParameters.isNotEmpty) {
        final named = spec.optionalParameters.any((p) => p.named);
        if (named) {
          output.write('{');
        } else {
          output.write('[');
        }
        var count = 0;
        for (final p in spec.optionalParameters) {
          count++;
          _visitParameter(p, output, optional: true, named: named);
          if (hasMultipleParameters ||
              spec.optionalParameters.length != count) {
            output.write(', ');
          }
        }
        if (named) {
          output.write('}');
        } else {
          output.write(']');
        }
      }
      output.write(')');
    }
    if (spec.body != null) {
      if (spec.modifier != null) {
        switch (spec.modifier!) {
          case MethodModifier.async:
            output.write(' async ');
            break;
          case MethodModifier.asyncStar:
            output.write(' async* ');
            break;
          case MethodModifier.syncStar:
            output.write(' sync* ');
            break;
        }
      }
      if (_isLambdaMethod(spec)) {
        output.write(' => ');
      } else {
        output.write(' { ');
      }
      spec.body!.accept(this, output);
      if (!_isLambdaMethod(spec)) {
        output.write(' } ');
      }
    } else {
      output.write(';');
    }
    return output;
  }

  // Expose as a first-class visit function only if needed.
  void _visitParameter(
    Parameter spec,
    StringSink output, {
    bool optional = false,
    bool named = false,
  }) {
    spec.docs.forEach(output.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, output);
    }
    // The `required` keyword must precede the `covariant` keyword.
    if (spec.required) {
      output.write('required ');
    }
    if (spec.covariant) {
      output.write('covariant ');
    }
    if (spec.type != null) {
      spec.type!.type.accept(this, output);
      output.write(' ');
    }
    if (spec.toThis) {
      output.write('this.');
    }
    if (spec.toSuper) {
      output.write('super.');
    }
    output.write(spec.name);
    if (optional && spec.defaultTo != null) {
      output.write(' = ');
      spec.defaultTo!.accept(this, output);
    }
  }

  void _visitMethods(Iterable<Method> methods, StringSink out) {
    for (final m in methods) {
      visitMethod(m, out);
      if (_isLambdaMethod(m)) {
        out.writeln(';');
      }
      out.writeln();
    }
  }

  @override
  StringSink visitReference(Reference spec, [StringSink? output]) =>
      (output ??= StringBuffer())..write(allocator.allocate(spec));

  @override
  StringSink visitSpec(Spec spec, [StringSink? output]) =>
      spec.accept(this, output);

  @override
  StringSink visitType(TypeReference spec, [StringSink? output]) {
    output ??= StringBuffer();
    // Intentionally not .accept to avoid stack overflow.
    visitReference(spec, output);
    if (spec.bound != null) {
      output.write(' extends ');
      spec.bound!.type.accept(this, output);
    }
    visitTypeParameters(spec.types.map((r) => r.type), output);
    if (_useNullSafetySyntax && (spec.isNullable ?? false)) {
      output.write('?');
    }
    return output;
  }

  @override
  StringSink visitTypeParameters(
    Iterable<Reference> specs, [
    StringSink? output,
  ]) {
    output ??= StringBuffer();
    if (specs.isNotEmpty) {
      output
        ..write('<')
        ..writeAll(specs.map<StringSink>((s) => s.accept(this)), ',')
        ..write('>');
    }
    return output;
  }

  @override
  StringSink visitEnum(Enum spec, [StringSink? output]) {
    final out = output ??= StringBuffer();
    spec.docs.forEach(out.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, out);
    }
    out.write('enum ${spec.name}');
    visitTypeParameters(spec.types.map((r) => r.type), out);
    if (spec.mixins.isNotEmpty) {
      out
        ..write(' with ')
        ..writeAll(
          spec.mixins.map<StringSink>((m) => m.type.accept(this)),
          ', ',
        );
    }
    if (spec.implements.isNotEmpty) {
      out
        ..write(' implements ')
        ..writeAll(
          spec.implements.map<StringSink>((m) => m.type.accept(this)),
          ', ',
        );
    }
    out.write(' { ');
    for (var v in spec.values) {
      v.docs.forEach(out.writeln);
      for (var a in v.annotations) {
        visitAnnotation(a, out);
      }
      out.write(v.name);
      if (v.constructorName != null) {
        out.write('.${v.constructorName}');
      }
      visitTypeParameters(v.types.map((r) => r.type), out);
      final takesArguments =
          v.constructorName != null ||
          v.arguments.isNotEmpty ||
          v.namedArguments.isNotEmpty;
      if (takesArguments) {
        out.write('(');
      }
      if (v.arguments.isNotEmpty) {
        out.writeAll(
          v.arguments.map<StringSink>((arg) => arg.accept(this)),
          ', ',
        );
      }
      if (v.arguments.isNotEmpty && v.namedArguments.isNotEmpty) {
        out.write(', ');
      }
      visitAll<String>(v.namedArguments.keys, out, (name) {
        out
          ..write(name)
          ..write(': ');
        v.namedArguments[name]!.accept(this, out);
      });
      if (takesArguments) {
        out.write(')');
      }
      if (v != spec.values.last) {
        out.writeln(',');
      } else if (spec.constructors.isNotEmpty ||
          spec.fields.isNotEmpty ||
          spec.methods.isNotEmpty) {
        out.writeln(';');
      }
    }
    for (var c in spec.constructors) {
      visitConstructor(c, spec.name, out);
      out.writeln();
    }
    for (var f in spec.fields) {
      visitField(f, out);
      out.writeln();
    }
    _visitMethods(spec.methods, out);
    out.writeln(' }');
    return out;
  }
}

/// Returns `true` if:
///
/// * [ordered] is `true`
/// * [a] is non-`null`
/// * If there should be an empty line before [b] if it's emitted after [a].
bool _newLineBetween(bool ordered, Directive? a, Directive? b) {
  if (!ordered) return false;
  if (a == null) return false;

  assert(b != null);

  // Put a line between imports and exports
  if (a.type != b!.type) return true;

  // Within exports, don't put in extra blank lines
  if (a.type == DirectiveType.export) {
    assert(b.type == DirectiveType.export);
    return false;
  }

  // Return `true` if the schemes for [a] and [b] are different
  return !Uri.parse(a.url).isScheme(Uri.parse(b.url).scheme);
}
