[pigeon] Relocates generator classes and updates imports (#2985)

* start

* Class file transfer and skeleton comments

* relocate generator classes and update imports

* merge main and changelog update
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 39ccd55..1c49f46 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 4.2.15
+
+* Relocates generator classes.
+
 ## 4.2.14
 
 * [c++] Fixes reply sending non EncodableValue wrapped lists.
diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart
index 744f6e9..8a714b2 100644
--- a/packages/pigeon/lib/cpp_generator.dart
+++ b/packages/pigeon/lib/cpp_generator.dart
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+import 'package:path/path.dart' as path;
+
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
-import 'pigeon_lib.dart' show Error;
+import 'pigeon_lib.dart' show Error, PigeonOptions, lineReader, openSink;
 
 /// General comment opening token.
 const String _commentPrefix = '//';
@@ -64,6 +68,54 @@
   }
 }
 
+/// A [Generator] that generates C++ header code.
+class CppHeaderGenerator implements Generator {
+  /// Constructor for [CppHeaderGenerator].
+  const CppHeaderGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final CppOptions cppOptions = options.cppOptions ?? const CppOptions();
+    final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateCppHeader(path.basenameWithoutExtension(options.cppHeaderOut!),
+        cppOptionsWithHeader, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) =>
+      openSink(options.cppHeaderOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) =>
+      validateCpp(options.cppOptions!, root);
+}
+
+/// A [Generator] that generates C++ source code.
+class CppSourceGenerator implements Generator {
+  /// Constructor for [CppSourceGenerator].
+  const CppSourceGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final CppOptions cppOptions = options.cppOptions ?? const CppOptions();
+    final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateCppSource(cppOptionsWithHeader, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) =>
+      openSink(options.cppSourceOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer';
 
 const String _pointerPrefix = 'pointer';
diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart
index 85956ce..4ab9ebd 100644
--- a/packages/pigeon/lib/dart_generator.dart
+++ b/packages/pigeon/lib/dart_generator.dart
@@ -2,14 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:io' show Directory, File, FileSystemEntity;
+import 'dart:io' show Directory, File, FileSystemEntity, IOSink;
 
 import 'package:path/path.dart' as path;
 import 'package:yaml/yaml.dart' as yaml;
 
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
+import 'pigeon_lib.dart' show Error, PigeonOptions, lineReader, openSink;
 
 /// Documentation comment open symbol.
 const String _docCommentPrefix = '///';
@@ -65,6 +67,64 @@
 /// Calculates the name of the codec class that will be generated for [api].
 String _getCodecName(Api api) => '_${api.name}Codec';
 
+/// A [Generator] that generates Dart source code.
+class DartGenerator implements Generator {
+  /// Constructor for [DartGenerator].
+  const DartGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader(
+        options.dartOptions, options.copyrightHeader);
+    generateDart(dartOptionsWithHeader, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) => openSink(options.dartOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
+DartOptions _dartOptionsWithCopyrightHeader(
+    DartOptions? dartOptions, String? copyrightHeader) {
+  dartOptions = dartOptions ?? const DartOptions();
+  return dartOptions.merge(DartOptions(
+      copyrightHeader:
+          copyrightHeader != null ? lineReader(copyrightHeader) : null));
+}
+
+/// A [Generator] that generates Dart test source code.
+class DartTestGenerator implements Generator {
+  /// Constructor for [DartTestGenerator].
+  const DartTestGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader(
+        options.dartOptions, options.copyrightHeader);
+    generateTestDart(
+      dartOptionsWithHeader,
+      root,
+      sink,
+      dartOutPath: options.dartOut!,
+      testOutPath: options.dartTestOut!,
+    );
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) {
+    if (options.dartTestOut != null) {
+      return openSink(options.dartTestOut);
+    } else {
+      return null;
+    }
+  }
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 /// Writes the codec that will be used by [api].
 /// Example:
 ///
diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart
new file mode 100644
index 0000000..8cdace2
--- /dev/null
+++ b/packages/pigeon/lib/generator.dart
@@ -0,0 +1,26 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+
+import 'ast.dart';
+import 'pigeon_lib.dart' show Error, PigeonOptions;
+
+/// A generator that will write code to a sink based on the contents of [PigeonOptions].
+abstract class Generator {
+  /// Constructor for Generator.
+  Generator();
+
+  /// Returns an [IOSink] instance to be written to if the [Generator] should
+  /// generate.  If it returns `null`, the [Generator] will be skipped.
+  IOSink? shouldGenerate(PigeonOptions options);
+
+  /// Write the generated code described in [root] to [sink] using the
+  /// [options].
+  void generate(StringSink sink, PigeonOptions options, Root root);
+
+  /// Generates errors that would only be appropriate for this [Generator]. For
+  /// example, maybe a certain feature isn't implemented in a [Generator] yet.
+  List<Error> validate(PigeonOptions options, Root root);
+}
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 4d8ed37..6624a1d 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -9,7 +9,7 @@
 import 'ast.dart';
 
 /// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '4.2.14';
+const String pigeonVersion = '4.2.15';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart
index c52d976..3d475bb 100644
--- a/packages/pigeon/lib/java_generator.dart
+++ b/packages/pigeon/lib/java_generator.dart
@@ -2,10 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
-import 'pigeon_lib.dart' show TaskQueueType;
+import 'pigeon_lib.dart'
+    show Error, PigeonOptions, TaskQueueType, lineReader, openSink;
 
 /// Documentation open symbol.
 const String _docCommentPrefix = '/**';
@@ -84,6 +90,30 @@
   }
 }
 
+/// A [Generator] that generates Java source code.
+class JavaGenerator implements Generator {
+  /// Constructor for [JavaGenerator].
+  const JavaGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    JavaOptions javaOptions = options.javaOptions ?? const JavaOptions();
+    javaOptions = javaOptions.merge(JavaOptions(
+        className: javaOptions.className ??
+            path.basenameWithoutExtension(options.javaOut!),
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateJava(javaOptions, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) => openSink(options.javaOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 /// Calculates the name of the codec that will be generated for [api].
 String _getCodecName(Api api) => '${api.name}Codec';
 
diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart
index 1f52d3d..72456e6 100644
--- a/packages/pigeon/lib/kotlin_generator.dart
+++ b/packages/pigeon/lib/kotlin_generator.dart
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
-import 'pigeon_lib.dart' show TaskQueueType;
+import 'pigeon_lib.dart'
+    show Error, PigeonOptions, TaskQueueType, lineReader, openSink;
 
 /// Documentation open symbol.
 const String _docCommentPrefix = '/**';
@@ -64,6 +68,29 @@
   }
 }
 
+/// A [Generator] that generates Kotlin source code.
+class KotlinGenerator implements Generator {
+  /// Constructor for [KotlinGenerator].
+  const KotlinGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    KotlinOptions kotlinOptions =
+        options.kotlinOptions ?? const KotlinOptions();
+    kotlinOptions = kotlinOptions.merge(KotlinOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateKotlin(kotlinOptions, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) => openSink(options.kotlinOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 /// Calculates the name of the codec that will be generated for [api].
 String _getCodecName(Api api) => '${api.name}Codec';
 
diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart
index e8de7c1..8e7caea 100644
--- a/packages/pigeon/lib/objc_generator.dart
+++ b/packages/pigeon/lib/objc_generator.dart
@@ -2,10 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
-import 'pigeon_lib.dart' show Error, TaskQueueType;
+import 'pigeon_lib.dart'
+    show Error, PigeonOptions, TaskQueueType, lineReader, openSink;
 
 /// Documentation comment open symbol.
 const String _docCommentPrefix = '///';
@@ -63,6 +67,53 @@
   }
 }
 
+/// A [Generator] that generates Objective-C header code.
+class ObjcHeaderGenerator implements Generator {
+  /// Constructor for [ObjcHeaderGenerator].
+  const ObjcHeaderGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions();
+    final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateObjcHeader(objcOptionsWithHeader, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) =>
+      openSink(options.objcHeaderOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) =>
+      validateObjc(options.objcOptions!, root);
+}
+
+/// A [Generator] that generates Objective-C source code.
+class ObjcSourceGenerator implements Generator {
+  /// Constructor for [ObjcSourceGenerator].
+  const ObjcSourceGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions();
+    final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateObjcSource(objcOptionsWithHeader, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) =>
+      openSink(options.objcSourceOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 /// Calculates the ObjC class name, possibly prefixed.
 String _className(String? prefix, String className) {
   if (prefix != null) {
diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart
index 5da91c4..6da35a5 100644
--- a/packages/pigeon/lib/pigeon_lib.dart
+++ b/packages/pigeon/lib/pigeon_lib.dart
@@ -27,6 +27,7 @@
 import 'ast_generator.dart';
 import 'cpp_generator.dart';
 import 'dart_generator.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
 import 'generator_tools.dart' as generator_tools;
 import 'java_generator.dart';
@@ -331,7 +332,8 @@
   final Map<String, Object>? pigeonOptions;
 }
 
-Iterable<String> _lineReader(String path) sync* {
+/// Reads file line by line.
+Iterable<String> lineReader(String path) sync* {
   final String contents = File(path).readAsStringSync();
   const LineSplitter lineSplitter = LineSplitter();
   final List<String> lines = lineSplitter.convert(contents);
@@ -340,7 +342,8 @@
   }
 }
 
-IOSink? _openSink(String? output) {
+/// Creates IOSink.
+IOSink? openSink(String? output) {
   if (output == null) {
     return null;
   }
@@ -355,29 +358,6 @@
   return sink;
 }
 
-/// A generator that will write code to a sink based on the contents of [PigeonOptions].
-abstract class Generator {
-  /// Returns an [IOSink] instance to be written to if the [Generator] should
-  /// generate.  If it returns `null`, the [Generator] will be skipped.
-  IOSink? shouldGenerate(PigeonOptions options);
-
-  /// Write the generated code described in [root] to [sink] using the
-  /// [options].
-  void generate(StringSink sink, PigeonOptions options, Root root);
-
-  /// Generates errors that would only be appropriate for this [Generator]. For
-  /// example, maybe a certain feature isn't implemented in a [Generator] yet.
-  List<Error> validate(PigeonOptions options, Root root);
-}
-
-DartOptions _dartOptionsWithCopyrightHeader(
-    DartOptions? dartOptions, String? copyrightHeader) {
-  dartOptions = dartOptions ?? const DartOptions();
-  return dartOptions.merge(DartOptions(
-      copyrightHeader:
-          copyrightHeader != null ? _lineReader(copyrightHeader) : null));
-}
-
 /// A [Generator] that generates the AST.
 class AstGenerator implements Generator {
   /// Constructor for [AstGenerator].
@@ -389,221 +369,7 @@
   }
 
   @override
-  IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.astOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Dart source code.
-class DartGenerator implements Generator {
-  /// Constructor for [DartGenerator].
-  const DartGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader(
-        options.dartOptions, options.copyrightHeader);
-    generateDart(dartOptionsWithHeader, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.dartOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Dart test source code.
-class DartTestGenerator implements Generator {
-  /// Constructor for [DartTestGenerator].
-  const DartTestGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader(
-        options.dartOptions, options.copyrightHeader);
-    generateTestDart(
-      dartOptionsWithHeader,
-      root,
-      sink,
-      dartOutPath: options.dartOut!,
-      testOutPath: options.dartTestOut!,
-    );
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) {
-    if (options.dartTestOut != null) {
-      return _openSink(options.dartTestOut);
-    } else {
-      return null;
-    }
-  }
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Objective-C header code.
-class ObjcHeaderGenerator implements Generator {
-  /// Constructor for [ObjcHeaderGenerator].
-  const ObjcHeaderGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions();
-    final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateObjcHeader(objcOptionsWithHeader, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) =>
-      _openSink(options.objcHeaderOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) =>
-      validateObjc(options.objcOptions!, root);
-}
-
-/// A [Generator] that generates Objective-C source code.
-class ObjcSourceGenerator implements Generator {
-  /// Constructor for [ObjcSourceGenerator].
-  const ObjcSourceGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions();
-    final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateObjcSource(objcOptionsWithHeader, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) =>
-      _openSink(options.objcSourceOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Java source code.
-class JavaGenerator implements Generator {
-  /// Constructor for [JavaGenerator].
-  const JavaGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    JavaOptions javaOptions = options.javaOptions ?? const JavaOptions();
-    javaOptions = javaOptions.merge(JavaOptions(
-        className: javaOptions.className ??
-            path.basenameWithoutExtension(options.javaOut!),
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateJava(javaOptions, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.javaOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Swift source code.
-class SwiftGenerator implements Generator {
-  /// Constructor for [SwiftGenerator].
-  const SwiftGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    SwiftOptions swiftOptions = options.swiftOptions ?? const SwiftOptions();
-    swiftOptions = swiftOptions.merge(SwiftOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateSwift(swiftOptions, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.swiftOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates C++ header code.
-class CppHeaderGenerator implements Generator {
-  /// Constructor for [CppHeaderGenerator].
-  const CppHeaderGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final CppOptions cppOptions = options.cppOptions ?? const CppOptions();
-    final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateCppHeader(path.basenameWithoutExtension(options.cppHeaderOut!),
-        cppOptionsWithHeader, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) =>
-      _openSink(options.cppHeaderOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) =>
-      validateCpp(options.cppOptions!, root);
-}
-
-/// A [Generator] that generates C++ source code.
-class CppSourceGenerator implements Generator {
-  /// Constructor for [CppSourceGenerator].
-  const CppSourceGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    final CppOptions cppOptions = options.cppOptions ?? const CppOptions();
-    final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateCppSource(cppOptionsWithHeader, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) =>
-      _openSink(options.cppSourceOut);
-
-  @override
-  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
-}
-
-/// A [Generator] that generates Kotlin source code.
-class KotlinGenerator implements Generator {
-  /// Constructor for [KotlinGenerator].
-  const KotlinGenerator();
-
-  @override
-  void generate(StringSink sink, PigeonOptions options, Root root) {
-    KotlinOptions kotlinOptions =
-        options.kotlinOptions ?? const KotlinOptions();
-    kotlinOptions = kotlinOptions.merge(KotlinOptions(
-        copyrightHeader: options.copyrightHeader != null
-            ? _lineReader(options.copyrightHeader!)
-            : null));
-    generateKotlin(kotlinOptions, root, sink);
-  }
-
-  @override
-  IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.kotlinOut);
+  IOSink? shouldGenerate(PigeonOptions options) => openSink(options.astOut);
 
   @override
   List<Error> validate(PigeonOptions options, Root root) => <Error>[];
diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart
index 3736506..5cceecc 100644
--- a/packages/pigeon/lib/swift_generator.dart
+++ b/packages/pigeon/lib/swift_generator.dart
@@ -2,9 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'dart:io';
+
 import 'ast.dart';
 import 'functional.dart';
+import 'generator.dart';
 import 'generator_tools.dart';
+import 'pigeon_lib.dart' show Error, PigeonOptions, lineReader, openSink;
 
 /// Documentation comment open symbol.
 const String _docCommentPrefix = '///';
@@ -47,6 +51,28 @@
   }
 }
 
+/// A [Generator] that generates Swift source code.
+class SwiftGenerator implements Generator {
+  /// Constructor for [SwiftGenerator].
+  const SwiftGenerator();
+
+  @override
+  void generate(StringSink sink, PigeonOptions options, Root root) {
+    SwiftOptions swiftOptions = options.swiftOptions ?? const SwiftOptions();
+    swiftOptions = swiftOptions.merge(SwiftOptions(
+        copyrightHeader: options.copyrightHeader != null
+            ? lineReader(options.copyrightHeader!)
+            : null));
+    generateSwift(swiftOptions, root, sink);
+  }
+
+  @override
+  IOSink? shouldGenerate(PigeonOptions options) => openSink(options.swiftOut);
+
+  @override
+  List<Error> validate(PigeonOptions options, Root root) => <Error>[];
+}
+
 /// Calculates the name of the codec that will be generated for [api].
 String _getCodecName(Api api) => '${api.name}Codec';
 
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index c6d4029..e9c9d6b 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
 repository: https://github.com/flutter/packages/tree/main/packages/pigeon
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon
-version: 4.2.14 # This must match the version in lib/generator_tools.dart
+version: 4.2.15 # This must match the version in lib/generator_tools.dart
 
 environment:
   sdk: ">=2.12.0 <3.0.0"
diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart
index 4a121e7..8106cac 100644
--- a/packages/pigeon/test/pigeon_lib_test.dart
+++ b/packages/pigeon/test/pigeon_lib_test.dart
@@ -6,7 +6,13 @@
 import 'dart:io';
 
 import 'package:pigeon/ast.dart';
+import 'package:pigeon/cpp_generator.dart';
+import 'package:pigeon/dart_generator.dart';
+import 'package:pigeon/generator.dart';
+import 'package:pigeon/java_generator.dart';
+import 'package:pigeon/objc_generator.dart';
 import 'package:pigeon/pigeon_lib.dart';
+import 'package:pigeon/swift_generator.dart';
 import 'package:test/test.dart';
 
 class _ValidatorGenerator implements Generator {