[pigeon] Add method to run pigeon with PigeonOptions (#2842)

* [pigeon] Add runWithOptions entrypoint to allow external libraries to use the pigeon easier

* [pigeon] 4.2.7 code review fixes

* [pigeon]: Bump version 4.2.8
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 37b6da9..9085b70 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 4.2.8
+
+* Adds the ability to use `runWithOptions` entrypoint to allow external libraries to use the pigeon easier.
+
 ## 4.2.7
 
 * [swift] Fixes a bug when calling methods that return `void`.
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 7916bda..156cfa9 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.7';
+const String pigeonVersion = '4.2.8';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart
index 2c04ed3..abab950 100644
--- a/packages/pigeon/lib/pigeon_lib.dart
+++ b/packages/pigeon/lib/pigeon_lib.dart
@@ -1332,9 +1332,18 @@
   /// customize the generators that pigeon will use. The optional parameter
   /// [sdkPath] allows you to specify the Dart SDK path.
   static Future<int> run(List<String> args,
+      {List<Generator>? generators, String? sdkPath}) {
+    final PigeonOptions options = Pigeon.parseArgs(args);
+    return runWithOptions(options, generators: generators, sdkPath: sdkPath);
+  }
+
+  /// The 'main' entrypoint used by external packages.  [options] is
+  /// used when running the code generator.  The optional parameter [generators] allows you to
+  /// customize the generators that pigeon will use. The optional parameter
+  /// [sdkPath] allows you to specify the Dart SDK path.
+  static Future<int> runWithOptions(PigeonOptions options,
       {List<Generator>? generators, String? sdkPath}) async {
     final Pigeon pigeon = Pigeon.setup();
-    PigeonOptions options = Pigeon.parseArgs(args);
     if (options.debugGenerators ?? false) {
       generator_tools.debugGenerators = true;
     }
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index baa21d2..54cb878 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.7 # This must match the version in lib/generator_tools.dart
+version: 4.2.8 # 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 120c6a2..4a121e7 100644
--- a/packages/pigeon/test/pigeon_lib_test.dart
+++ b/packages/pigeon/test/pigeon_lib_test.dart
@@ -1210,4 +1210,18 @@
     });
     await completer.future;
   });
+
+  test('run with PigeonOptions', () async {
+    final Completer<void> completer = Completer<void>();
+    withTempFile('foo.dart', (File input) async {
+      final _ValidatorGenerator generator = _ValidatorGenerator(null);
+      final int result = await Pigeon.runWithOptions(
+          PigeonOptions(input: input.path, dartOut: 'foo.dart'),
+          generators: <Generator>[generator]);
+      expect(generator.didCallValidate, isFalse);
+      expect(result, equals(0));
+      completer.complete();
+    });
+    await completer.future;
+  });
 }