// 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();
    }

    // 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(';');
      }
    }

    final header = StringBuffer();
    spec.docs.forEach(header.writeln);
    for (var a in spec.annotations) {
      visitAnnotation(a, header);
    }
    if (spec.name != null) {
      header.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.
      header.write('library;');
    }

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

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

    final ignores = [
      ...spec.ignoreForFile,
      if (directives.any((d) => d.as?.startsWith('_') ?? false))
        'no_leading_underscores_for_library_prefixes',
    ];

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

    output.write(header);

    Directive? previous;
    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);
}
