[pigeon] Make Linux type declarations public (#8040)

Moves codec and HostAPI class declarations to the header to work around a glib bug. We could instead add an unnecessary call to the type check method, but we will need the codec to be public eventually anyway, and HostApi is conceptually a public class (it just isn't strictly necessary to declare it in the header due to the way abstract interfaces work in gobject) so may as well be declared publicly.

Part of https://github.com/flutter/flutter/issues/153083
diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index 85842f0..d93dd1b 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 22.6.1
+
+* [gobject] Moves class declarations to the header to work around a bug in some
+  versions of glib.
+
 ## 22.6.0
 
 * [swift] Adds `includeErrorClass` to `SwiftOptions`.
diff --git a/packages/pigeon/example/app/linux/messages.g.cc b/packages/pigeon/example/app/linux/messages.g.cc
index a9ee210..4471586 100644
--- a/packages/pigeon/example/app/linux/messages.g.cc
+++ b/packages/pigeon/example/app/linux/messages.g.cc
@@ -118,11 +118,6 @@
   return pigeon_example_package_message_data_new(name, description, code, data);
 }
 
-G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageCodec,
-                     pigeon_example_package_message_codec,
-                     PIGEON_EXAMPLE_PACKAGE, MESSAGE_CODEC,
-                     FlStandardMessageCodec)
-
 struct _PigeonExamplePackageMessageCodec {
   FlStandardMessageCodec parent_instance;
 };
@@ -468,10 +463,6 @@
   return self;
 }
 
-G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApi,
-                     pigeon_example_package_example_host_api,
-                     PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API, GObject)
-
 struct _PigeonExamplePackageExampleHostApi {
   GObject parent_instance;
 
diff --git a/packages/pigeon/example/app/linux/messages.g.h b/packages/pigeon/example/app/linux/messages.g.h
index 0f784ab..ac8dc92 100644
--- a/packages/pigeon/example/app/linux/messages.g.h
+++ b/packages/pigeon/example/app/linux/messages.g.h
@@ -90,6 +90,15 @@
 FlValue* pigeon_example_package_message_data_get_data(
     PigeonExamplePackageMessageData* object);
 
+G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageCodec,
+                     pigeon_example_package_message_codec,
+                     PIGEON_EXAMPLE_PACKAGE, MESSAGE_CODEC,
+                     FlStandardMessageCodec)
+
+G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApi,
+                     pigeon_example_package_example_host_api,
+                     PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API, GObject)
+
 G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApiResponseHandle,
                      pigeon_example_package_example_host_api_response_handle,
                      PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API_RESPONSE_HANDLE,
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index cbec3e8..8349285 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -14,7 +14,7 @@
 /// The current version of pigeon.
 ///
 /// This must match the version in pubspec.yaml.
-const String pigeonVersion = '22.6.0';
+const String pigeonVersion = '22.6.1';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/gobject_generator.dart b/packages/pigeon/lib/gobject_generator.dart
index bee0380..04f4bd1 100644
--- a/packages/pigeon/lib/gobject_generator.dart
+++ b/packages/pigeon/lib/gobject_generator.dart
@@ -14,6 +14,9 @@
 /// Name for codec class.
 const String _codecBaseName = 'MessageCodec';
 
+/// Name of the standard codec from the Flutter SDK.
+const String _standardCodecName = 'FlStandardMessageCodec';
+
 /// Options that control how GObject code will be generated.
 class GObjectOptions {
   /// Creates a [GObjectOptions] object
@@ -282,7 +285,12 @@
     Root root,
     Indent indent, {
     required String dartPackageName,
-  }) {}
+  }) {
+    final String module = _getModule(generatorOptions, dartPackageName);
+    indent.newln();
+    _writeDeclareFinalType(indent, module, _codecBaseName,
+        parentClassName: _standardCodecName);
+  }
 
   @override
   void writeFlutterApi(
@@ -508,6 +516,9 @@
     final String methodPrefix = _getMethodPrefix(module, api.name);
     final String vtableName = _getVTableName(module, api.name);
 
+    indent.newln();
+    _writeDeclareFinalType(indent, module, api.name);
+
     final bool hasAsyncMethod =
         api.methods.any((Method method) => method.isAsynchronous);
     if (hasAsyncMethod) {
@@ -951,12 +962,8 @@
     final Iterable<EnumeratedType> customTypes = getEnumeratedTypes(root);
 
     indent.newln();
-    _writeDeclareFinalType(indent, module, _codecBaseName,
-        parentClassName: 'FlStandardMessageCodec');
-
-    indent.newln();
     _writeObjectStruct(indent, module, _codecBaseName, () {},
-        parentClassName: 'FlStandardMessageCodec');
+        parentClassName: _standardCodecName);
 
     indent.newln();
     _writeDefineType(indent, module, _codecBaseName,
@@ -971,7 +978,7 @@
           ? '$customTypeName*'
           : 'FlValue*';
       indent.writeScoped(
-          'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName(FlStandardMessageCodec* codec, GByteArray* buffer, $valueType value, GError** error) {',
+          'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName($_standardCodecName* codec, GByteArray* buffer, $valueType value, GError** error) {',
           '}', () {
         indent.writeln('uint8_t type = ${customType.enumeration};');
         indent.writeln('g_byte_array_append(buffer, &type, sizeof(uint8_t));');
@@ -989,7 +996,7 @@
 
     indent.newln();
     indent.writeScoped(
-        'static gboolean ${codecMethodPrefix}_write_value(FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value, GError** error) {',
+        'static gboolean ${codecMethodPrefix}_write_value($_standardCodecName* codec, GByteArray* buffer, FlValue* value, GError** error) {',
         '}', () {
       indent.writeScoped(
           'if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) {', '}', () {
@@ -1027,7 +1034,7 @@
           _snakeCaseFromCamelCase(customTypeName);
       indent.newln();
       indent.writeScoped(
-          'static FlValue* ${codecMethodPrefix}_read_$snakeCustomTypeName(FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, GError** error) {',
+          'static FlValue* ${codecMethodPrefix}_read_$snakeCustomTypeName($_standardCodecName* codec, GBytes* buffer, size_t* offset, GError** error) {',
           '}', () {
         if (customType.type == CustomTypes.customClass) {
           indent.writeln(
@@ -1055,7 +1062,7 @@
 
     indent.newln();
     indent.writeScoped(
-        'static FlValue* ${codecMethodPrefix}_read_value_of_type(FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type, GError** error) {',
+        'static FlValue* ${codecMethodPrefix}_read_value_of_type($_standardCodecName* codec, GBytes* buffer, size_t* offset, int type, GError** error) {',
         '}', () {
       indent.writeScoped('switch (type) {', '}', () {
         for (final EnumeratedType customType in customTypes) {
@@ -1474,9 +1481,6 @@
     }
 
     indent.newln();
-    _writeDeclareFinalType(indent, module, api.name);
-
-    indent.newln();
     _writeObjectStruct(indent, module, api.name, () {
       indent.writeln('const ${className}VTable* vtable;');
       indent.writeln('gpointer user_data;');
diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc
index 5701f91..8dee0b4 100644
--- a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc
+++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.cc
@@ -2397,11 +2397,6 @@
   return core_tests_pigeon_test_test_message_new(test_list);
 }
 
-G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestMessageCodec,
-                     core_tests_pigeon_test_message_codec,
-                     CORE_TESTS_PIGEON_TEST, MESSAGE_CODEC,
-                     FlStandardMessageCodec)
-
 struct _CoreTestsPigeonTestMessageCodec {
   FlStandardMessageCodec parent_instance;
 };
@@ -13564,10 +13559,6 @@
   return self;
 }
 
-G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostIntegrationCoreApi,
-                     core_tests_pigeon_test_host_integration_core_api,
-                     CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API, GObject)
-
 struct _CoreTestsPigeonTestHostIntegrationCoreApi {
   GObject parent_instance;
 
@@ -32742,10 +32733,6 @@
   return self;
 }
 
-G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostTrivialApi,
-                     core_tests_pigeon_test_host_trivial_api,
-                     CORE_TESTS_PIGEON_TEST, HOST_TRIVIAL_API, GObject)
-
 struct _CoreTestsPigeonTestHostTrivialApi {
   GObject parent_instance;
 
@@ -33021,10 +33008,6 @@
   return self;
 }
 
-G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApi,
-                     core_tests_pigeon_test_host_small_api,
-                     CORE_TESTS_PIGEON_TEST, HOST_SMALL_API, GObject)
-
 struct _CoreTestsPigeonTestHostSmallApi {
   GObject parent_instance;
 
diff --git a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h
index 6cb79ba..dcd6cac 100644
--- a/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h
+++ b/packages/pigeon/platform_tests/test_plugin/linux/pigeon/core_tests.gen.h
@@ -1428,6 +1428,15 @@
 FlValue* core_tests_pigeon_test_test_message_get_test_list(
     CoreTestsPigeonTestTestMessage* object);
 
+G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestMessageCodec,
+                     core_tests_pigeon_test_message_codec,
+                     CORE_TESTS_PIGEON_TEST, MESSAGE_CODEC,
+                     FlStandardMessageCodec)
+
+G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostIntegrationCoreApi,
+                     core_tests_pigeon_test_host_integration_core_api,
+                     CORE_TESTS_PIGEON_TEST, HOST_INTEGRATION_CORE_API, GObject)
+
 G_DECLARE_FINAL_TYPE(
     CoreTestsPigeonTestHostIntegrationCoreApiResponseHandle,
     core_tests_pigeon_test_host_integration_core_api_response_handle,
@@ -11869,6 +11878,10 @@
     CoreTestsPigeonTestFlutterIntegrationCoreApi* api, GAsyncResult* result,
     GError** error);
 
+G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostTrivialApi,
+                     core_tests_pigeon_test_host_trivial_api,
+                     CORE_TESTS_PIGEON_TEST, HOST_TRIVIAL_API, GObject)
+
 G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostTrivialApiNoopResponse,
                      core_tests_pigeon_test_host_trivial_api_noop_response,
                      CORE_TESTS_PIGEON_TEST, HOST_TRIVIAL_API_NOOP_RESPONSE,
@@ -11936,6 +11949,10 @@
 void core_tests_pigeon_test_host_trivial_api_clear_method_handlers(
     FlBinaryMessenger* messenger, const gchar* suffix);
 
+G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApi,
+                     core_tests_pigeon_test_host_small_api,
+                     CORE_TESTS_PIGEON_TEST, HOST_SMALL_API, GObject)
+
 G_DECLARE_FINAL_TYPE(CoreTestsPigeonTestHostSmallApiResponseHandle,
                      core_tests_pigeon_test_host_small_api_response_handle,
                      CORE_TESTS_PIGEON_TEST, HOST_SMALL_API_RESPONSE_HANDLE,
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index cddaae5..31b7362 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%3A%22p%3A+pigeon%22
-version: 22.6.0 # This must match the version in lib/generator_tools.dart
+version: 22.6.1 # This must match the version in lib/generator_tools.dart
 
 environment:
   sdk: ^3.3.0
diff --git a/packages/pigeon/test/gobject_generator_test.dart b/packages/pigeon/test/gobject_generator_test.dart
index 935e9b9..3b9d90a 100644
--- a/packages/pigeon/test/gobject_generator_test.dart
+++ b/packages/pigeon/test/gobject_generator_test.dart
@@ -95,6 +95,10 @@
           code,
           contains(
               'static void test_package_api_init(TestPackageApi* self) {'));
+      // See https://github.com/flutter/flutter/issues/153083. If a private type
+      // is ever needed, this should be updated to ensure that any type declared
+      // in the implementation file has a corresponding _IS_ call in the file.
+      expect(code, isNot(contains('G_DECLARE_FINAL_TYPE(')));
     }
   });