[Pigeon] Add one_language flag to pigeon (#419)

diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 6be42dc..1ed1635 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -5,6 +5,7 @@
 * [front-end] Added more errors for incorrect usage of Pigeon (previously they were just ignored).
 * Moved Pigeon to using a custom codec which allows collection types to contain custom classes.
 * Started allowing primitive data types as arguments and return types.
+* Added one_language flag for allowing Pigeon to only generate code for one platform.
 
 ## 0.3.0
 
diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart
index a125222..51cf303 100644
--- a/packages/pigeon/lib/pigeon_lib.dart
+++ b/packages/pigeon/lib/pigeon_lib.dart
@@ -115,7 +115,8 @@
       this.javaOut,
       this.javaOptions,
       this.dartOptions,
-      this.copyrightHeader});
+      this.copyrightHeader,
+      this.oneLanguage});
 
   /// Path to the file which will be processed.
   final String? input;
@@ -147,6 +148,9 @@
   /// Path to a copyright header that will get prepended to generated code.
   final String? copyrightHeader;
 
+  /// If Pigeon allows generating code for one language.
+  final bool? oneLanguage;
+
   /// Creates a [PigeonOptions] from a Map representation where:
   /// `x = PigeonOptions.fromMap(x.toMap())`.
   static PigeonOptions fromMap(Map<String, Object> map) {
@@ -167,6 +171,7 @@
           ? DartOptions.fromMap((map['dartOptions'] as Map<String, Object>?)!)
           : null,
       copyrightHeader: map['copyrightHeader'] as String?,
+      oneLanguage: map['oneLanguage'] as bool?,
     );
   }
 
@@ -806,7 +811,8 @@
   static final ArgParser _argParser = ArgParser()
     ..addOption('input', help: 'REQUIRED: Path to pigeon file.')
     ..addOption('dart_out',
-        help: 'REQUIRED: Path to generated Dart source file (.dart).')
+        help: 'Path to generated Dart source file (.dart). '
+            'Required if one_language is not specified.')
     ..addOption('dart_test_out',
         help: 'Path to generated library for Dart tests, when using '
             '@HostApi(dartHostTestHandler:).')
@@ -824,7 +830,10 @@
         help: 'Prefix for generated Objective-C classes and protocols.')
     ..addOption('copyright_header',
         help:
-            'Path to file with copyright header to be prepended to generated code.');
+            'Path to file with copyright header to be prepended to generated code.')
+    ..addFlag('one_language',
+        help: 'Allow Pigeon to only generate code for one language.',
+        defaultsTo: false);
 
   /// Convert command-line arguments to [PigeonOptions].
   static PigeonOptions parseArgs(List<String> args) {
@@ -851,6 +860,7 @@
         isNullSafe: results['dart_null_safety'],
       ),
       copyrightHeader: results['copyright_header'],
+      oneLanguage: results['one_language'],
     );
     return opts;
   }
@@ -891,7 +901,8 @@
         ];
     _executeConfigurePigeon(options);
 
-    if (options.input == null || options.dartOut == null) {
+    if (options.input == null ||
+        (options.oneLanguage == false && options.dartOut == null)) {
       print(usage);
       return 0;
     }
diff --git a/packages/pigeon/run_tests.sh b/packages/pigeon/run_tests.sh
index 3419675..2a12484 100755
--- a/packages/pigeon/run_tests.sh
+++ b/packages/pigeon/run_tests.sh
@@ -193,6 +193,16 @@
   $run_pigeon 1>/dev/null
 }
 
+# Test one_language flag. With this flag specified, java_out can be generated
+# without dart_out.
+test_one_language_flag() {
+  $run_pigeon \
+    --input pigeons/message.dart \
+    --one_language \
+    --java_out stdout \
+    | grep "public class Message">/dev/null
+}
+
 run_flutter_unittests() {
   pushd $PWD
   $run_pigeon \
@@ -294,6 +304,8 @@
 }
 
 run_android_unittests() {
+  test_one_language_flag
+
   pushd $PWD
   gen_android_unittests_code ./pigeons/all_datatypes.dart AllDatatypes
   gen_android_unittests_code ./pigeons/all_void.dart AllVoid
diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart
index 6aba0a0..b171fea 100644
--- a/packages/pigeon/test/pigeon_lib_test.dart
+++ b/packages/pigeon/test/pigeon_lib_test.dart
@@ -70,6 +70,11 @@
     expect(opts.objcSourceOut, equals('foo.m'));
   });
 
+  test('parse args - one_language', () {
+    final PigeonOptions opts = Pigeon.parseArgs(<String>['--one_language']);
+    expect(opts.oneLanguage, isTrue);
+  });
+
   test('simple parse api', () {
     const String code = '''
 class Input1 {