Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pigeon] Kotlin implementation for ProxyApis #6371

Merged
merged 115 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 114 commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
7d66bf7
add other stuff
bparrishMines Mar 21, 2024
d64d2a2
add partial generator code
bparrishMines Mar 21, 2024
b64d723
add generated file
bparrishMines Mar 21, 2024
89d3c92
finish additions
bparrishMines Mar 21, 2024
1f7d0ad
some fixes
bparrishMines Mar 21, 2024
fa3c943
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 10, 2024
2665c22
add onWriteBody
bparrishMines Apr 11, 2024
cadf14c
use a common method for api math
bparrishMines Apr 15, 2024
2bf6738
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 15, 2024
6437fc9
add all stuff back
bparrishMines Apr 15, 2024
aea71cd
changelogg
bparrishMines Apr 15, 2024
0c09e91
formatting
bparrishMines Apr 16, 2024
f114c8c
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 16, 2024
d57ac0d
fix proxy api separated suffix
bparrishMines Apr 16, 2024
ff1e210
switch to a registrar
bparrishMines Apr 16, 2024
7e345ac
docs
bparrishMines Apr 16, 2024
db2a198
formatting
bparrishMines Apr 16, 2024
a7c94e5
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 16, 2024
7af4343
fix unit tests
bparrishMines Apr 16, 2024
a7b20a0
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 16, 2024
f2a1d5b
improve helper method and add test
bparrishMines Apr 17, 2024
f76265e
add a setter for clearFinalizedWeakReferencesInterval
bparrishMines Apr 17, 2024
b8e70f6
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 17, 2024
4f2327d
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Apr 24, 2024
5ade010
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 7, 2024
3b3a91b
return empty list in removeStrongReference
bparrishMines May 7, 2024
ec37d62
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 9, 2024
186fe47
update generated file
bparrishMines May 9, 2024
894e642
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 15, 2024
118606a
make private codec accessible and use open for pigeonRegistrar
bparrishMines May 20, 2024
4e821cb
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 20, 2024
4205418
nits
bparrishMines May 20, 2024
258653b
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 24, 2024
5070f6e
shared channel code for instancemanagerapi
bparrishMines May 29, 2024
06d163b
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 29, 2024
79e994b
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines May 30, 2024
1b9dfc1
make fullclassname nullable
bparrishMines May 30, 2024
f91a51f
use name constants and add a computation to the proxy api
bparrishMines May 30, 2024
84e0a0c
fix unit tests
bparrishMines May 30, 2024
bdf1aae
test api registrar
bparrishMines May 30, 2024
2ff9075
support a default api implementation
bparrishMines May 30, 2024
b0569f5
update instancemanager docs
bparrishMines Jun 3, 2024
4f47756
stops
bparrishMines Jun 3, 2024
03d1100
switch to format
bparrishMines Jun 4, 2024
c49aff2
regen and no ps
bparrishMines Jun 4, 2024
c7e5ad0
use addDocumenetationCommetns instead
bparrishMines Jun 4, 2024
d1883be
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 4, 2024
3025438
use write scoped
bparrishMines Jun 4, 2024
9af2d08
use indentscoped
bparrishMines Jun 4, 2024
78128b8
use format
bparrishMines Jun 4, 2024
84879d2
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 4, 2024
90f38b6
fix api check probably
bparrishMines Jun 4, 2024
505b500
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 11, 2024
172ef36
update codecs to be compatible
bparrishMines Jun 11, 2024
c294d49
analyze error fix
bparrishMines Jun 12, 2024
eaf1302
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 12, 2024
03f8a9e
dont use raw when passing enums and test parent codec
bparrishMines Jun 12, 2024
6a57229
formatting
bparrishMines Jun 12, 2024
38ab4a1
verify api requirements work
bparrishMines Jun 17, 2024
78ade11
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 17, 2024
fcb3aa5
use helper method
bparrishMines Jun 21, 2024
61579bc
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jun 28, 2024
c981d97
update format trim indentation
bparrishMines Jul 12, 2024
60be3da
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 12, 2024
0b7de44
also check nullable can return nonnull
bparrishMines Jul 12, 2024
8974f28
update to use file specific prefixes
bparrishMines Jul 16, 2024
4ae228d
fix test
bparrishMines Jul 16, 2024
e5ad0ce
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 16, 2024
77ac326
logging has name limits
bparrishMines Jul 16, 2024
33e3742
add file prefix
bparrishMines Jul 16, 2024
927aeea
test fix hopefullY
bparrishMines Jul 16, 2024
ce65169
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 17, 2024
1dd1eda
gen without formatting
bparrishMines Jul 19, 2024
bd08aa0
same code no gens
bparrishMines Jul 19, 2024
b2ae858
formatting
bparrishMines Jul 19, 2024
b2b82f6
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 19, 2024
4627f4a
formatting
bparrishMines Jul 19, 2024
abe2c0d
check supported types first
bparrishMines Jul 29, 2024
92a7370
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 29, 2024
6d5b581
maybe fix kotlin
bparrishMines Jul 29, 2024
770b24c
M`erge branch 'main' of github.com:flutter/packages into pigeon_kotli…
bparrishMines Jul 29, 2024
9e59393
add ignoreCallsToDart
bparrishMines Jul 31, 2024
bc60c15
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Jul 31, 2024
cb10073
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 9, 2024
3b3284a
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 15, 2024
cae65e8
fix kotlin tests and add kotlin prefixes
bparrishMines Aug 15, 2024
82f0cee
fix tools version
bparrishMines Aug 15, 2024
233acf5
fix lint
bparrishMines Aug 15, 2024
e810a8f
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 15, 2024
b95997e
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 16, 2024
24daaa1
try fix instance manager api name
bparrishMines Aug 17, 2024
f0aa519
fix tests
bparrishMines Aug 17, 2024
fed5b58
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 17, 2024
ccb1783
fix unit tests
bparrishMines Aug 17, 2024
0a2a643
fix log name
bparrishMines Aug 17, 2024
942918b
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 23, 2024
89abc69
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 26, 2024
cc55be5
regen code
bparrishMines Aug 26, 2024
41fca50
try lowering version
bparrishMines Aug 26, 2024
78e1e48
fix codec name in instancemanagerapi
bparrishMines Aug 27, 2024
e844875
fix kotlin api too
bparrishMines Aug 27, 2024
af2965f
regen
bparrishMines Aug 27, 2024
25d4515
raise version again
bparrishMines Aug 27, 2024
c5a083e
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 27, 2024
676eb05
some docs
bparrishMines Aug 27, 2024
f7b662a
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 29, 2024
d79c8f0
review comments
bparrishMines Aug 29, 2024
f4ac560
fix other comments locations
bparrishMines Aug 29, 2024
f70c2f1
include gen file actually
bparrishMines Aug 29, 2024
c1f23ae
analyze error
bparrishMines Aug 29, 2024
b958879
codec is not private since it is used in registrar
bparrishMines Aug 29, 2024
ecf079c
Merge branch 'main' of github.com:flutter/packages into pigeon_kotlin…
bparrishMines Aug 29, 2024
98d088f
fix unit test
bparrishMines Aug 29, 2024
923e21e
use messagecodec instead
bparrishMines Aug 29, 2024
f9d5b78
version bump
bparrishMines Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 22.1.0

* [kotlin] Adds implementation for `@ProxyApi`.

## 22.0.0

* [dart] Changes codec to send int64 instead of int32.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ data class MessageData(
}
}

private object MessagesPigeonCodec : StandardMessageCodec() {
private open class MessagesPigeonCodec : StandardMessageCodec() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think open classes also need methods to be marked open so this change is a no op for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some experimentation with a Kotlin interpreter, it looks like this doesn't apply to methods that are inherited from an interface. The ProxyApiBaseCodec override the interface methods from MessageCodec which seem to always be inherently open.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks that is not a level of kotlin nuance I would have known.

override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
129.toByte() -> {
Expand Down Expand Up @@ -122,7 +122,7 @@ interface ExampleHostApi {

companion object {
/** The codec used by ExampleHostApi. */
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec }
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec() }
/** Sets up an instance of `ExampleHostApi` to handle messages through the `binaryMessenger`. */
@JvmOverloads
fun setUp(
Expand Down Expand Up @@ -209,7 +209,7 @@ class MessageFlutterApi(
) {
companion object {
/** The codec used by MessageFlutterApi. */
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec }
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec() }
}

fun flutterMethod(aStringArg: String?, callback: (Result<String>) -> Unit) {
Expand Down
24 changes: 23 additions & 1 deletion packages/pigeon/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

import 'package:collection/collection.dart' show ListEquality;
import 'package:meta/meta.dart';

import 'generator_tools.dart';
import 'kotlin_generator.dart' show KotlinProxyApiOptions;
import 'pigeon_lib.dart';

typedef _ListEquals = bool Function(List<Object?>, List<Object?>);
Expand Down Expand Up @@ -140,6 +142,7 @@ class AstProxyApi extends Api {
required this.fields,
this.superClass,
this.interfaces = const <TypeDeclaration>{},
this.kotlinOptions,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need Kotlin options in a class that's currently unaware of specific generators?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the generated code references the native class, each ProxyApi needs to provide the full class name with the package. I also think Method.swiftFunction is similar since it provides additional instructions for the Swift generator.

});

/// List of constructors inside the API.
Expand All @@ -154,6 +157,10 @@ class AstProxyApi extends Api {
/// Name of the classes this class considers to be implemented.
Set<TypeDeclaration> interfaces;

/// Options that control how Kotlin code will be generated for a specific
/// ProxyApi.
final KotlinProxyApiOptions? kotlinOptions;

/// Methods implemented in the host platform language.
Iterable<Method> get hostMethods => methods.where(
(Method method) => method.location == ApiLocation.host,
Expand Down Expand Up @@ -253,7 +260,7 @@ class AstProxyApi extends Api {
}
}

/// Whether the api has a method that callbacks to Dart to add a new instance
/// Whether the API has a method that callbacks to Dart to add a new instance
/// to the InstanceManager.
///
/// This is possible as long as no callback methods are required to
Expand All @@ -265,6 +272,21 @@ class AstProxyApi extends Api {
.every((Method method) => !method.isRequired);
}

/// Whether the API has any message calls from Dart to host.
bool hasAnyHostMessageCalls() =>
constructors.isNotEmpty ||
attachedFields.isNotEmpty ||
hostMethods.isNotEmpty;

/// Whether the API has any message calls from host to Dart.
bool hasAnyFlutterMessageCalls() =>
hasCallbackConstructor() || flutterMethods.isNotEmpty;

/// Whether the host proxy API class will have methods that need to be
/// implemented.
bool hasMethodsRequiringImplementation() =>
hasAnyHostMessageCalls() || unattachedFields.isNotEmpty;

// Recursively search for all the interfaces apis from a list of names of
// interfaces.
//
Expand Down
48 changes: 31 additions & 17 deletions packages/pigeon/lib/dart/templates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@

import '../generator_tools.dart';

/// Name for the generated InstanceManager for ProxyApis.
///
/// This lowers the chances of variable name collisions with user defined
/// parameters.
const String dartInstanceManagerClassName =
'${proxyApiClassNamePrefix}InstanceManager';

/// Name for the generated InstanceManager API for ProxyApis.
///
/// This lowers the chances of variable name collisions with user defined
/// parameters.
const String dartInstanceManagerApiClassName =
'_${classNamePrefix}InstanceManagerApi';

/// Creates the `InstanceManager` with the passed string values.
String instanceManagerTemplate({
required Iterable<String> allProxyApiNames,
Expand All @@ -30,9 +44,9 @@ String instanceManagerTemplate({
/// is added as a weak reference with the same identifier. This prevents a
/// scenario where the weak referenced instance was released and then later
/// returned by the host platform.
class $instanceManagerClassName {
/// Constructs a [$instanceManagerClassName].
$instanceManagerClassName({required void Function(int) onWeakReferenceRemoved}) {
class $dartInstanceManagerClassName {
/// Constructs a [$dartInstanceManagerClassName].
$dartInstanceManagerClassName({required void Function(int) onWeakReferenceRemoved}) {
this.onWeakReferenceRemoved = (int identifier) {
_weakInstances.remove(identifier);
onWeakReferenceRemoved(identifier);
Expand All @@ -46,12 +60,12 @@ class $instanceManagerClassName {
// 0 <= n < 2^16.
static const int _maxDartCreatedIdentifier = 65536;

/// The default [$instanceManagerClassName] used by ProxyApis.
/// The default [$dartInstanceManagerClassName] used by ProxyApis.
///
/// On creation, this manager makes a call to clear the native
/// InstanceManager. This is to prevent identifier conflicts after a host
/// restart.
static final $instanceManagerClassName instance = _initInstance();
static final $dartInstanceManagerClassName instance = _initInstance();

// Expando is used because it doesn't prevent its keys from becoming
// inaccessible. This allows the manager to efficiently retrieve an identifier
Expand All @@ -72,17 +86,17 @@ class $instanceManagerClassName {
/// or becomes inaccessible.
late final void Function(int) onWeakReferenceRemoved;

static $instanceManagerClassName _initInstance() {
static $dartInstanceManagerClassName _initInstance() {
WidgetsFlutterBinding.ensureInitialized();
final _${instanceManagerClassName}Api api = _${instanceManagerClassName}Api();
// Clears the native `$instanceManagerClassName` on the initial use of the Dart one.
final $dartInstanceManagerApiClassName api = $dartInstanceManagerApiClassName();
// Clears the native `$dartInstanceManagerClassName` on the initial use of the Dart one.
api.clear();
final $instanceManagerClassName instanceManager = $instanceManagerClassName(
final $dartInstanceManagerClassName instanceManager = $dartInstanceManagerClassName(
onWeakReferenceRemoved: (int identifier) {
api.removeStrongReference(identifier);
},
);
_${instanceManagerClassName}Api.setUpMessageHandlers(instanceManager: instanceManager);
$dartInstanceManagerApiClassName.setUpMessageHandlers(instanceManager: instanceManager);
${apiHandlerSetUps.join('\n\t\t')}
return instanceManager;
}
Expand Down Expand Up @@ -229,9 +243,9 @@ abstract class $proxyApiBaseClassName {
/// Construct a [$proxyApiBaseClassName].
$proxyApiBaseClassName({
this.$_proxyApiBaseClassMessengerVarName,
$instanceManagerClassName? $_proxyApiBaseClassInstanceManagerVarName,
$dartInstanceManagerClassName? $_proxyApiBaseClassInstanceManagerVarName,
}) : $_proxyApiBaseClassInstanceManagerVarName =
$_proxyApiBaseClassInstanceManagerVarName ?? $instanceManagerClassName.instance;
$_proxyApiBaseClassInstanceManagerVarName ?? $dartInstanceManagerClassName.instance;

/// Sends and receives binary data across the Flutter platform barrier.
///
Expand All @@ -242,12 +256,12 @@ abstract class $proxyApiBaseClassName {

/// Maintains instances stored to communicate with native language objects.
@protected
final $instanceManagerClassName $_proxyApiBaseClassInstanceManagerVarName;
final $dartInstanceManagerClassName $_proxyApiBaseClassInstanceManagerVarName;

/// Instantiates and returns a functionally identical object to oneself.
///
/// Outside of tests, this method should only ever be called by
/// [$instanceManagerClassName].
/// [$dartInstanceManagerClassName].
///
/// Subclasses should always override their parent's implementation of this
/// method.
Expand All @@ -264,11 +278,11 @@ abstract class $proxyApiBaseClassName {
const String proxyApiBaseCodec = '''
class $_proxyApiCodecName extends _PigeonCodec {
const $_proxyApiCodecName(this.instanceManager);
final $instanceManagerClassName instanceManager;
final $dartInstanceManagerClassName instanceManager;
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is $proxyApiBaseClassName) {
buffer.putUint8(128);
buffer.putUint8($proxyApiCodecInstanceManagerKey);
writeValue(buffer, instanceManager.getIdentifier(value));
} else {
super.writeValue(buffer, value);
Expand All @@ -277,7 +291,7 @@ class $_proxyApiCodecName extends _PigeonCodec {
@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
case 128:
case $proxyApiCodecInstanceManagerKey:
return instanceManager
.getInstanceWithWeakReference(readValue(buffer)! as int);
default:
Expand Down
Loading