Repository: flutter
Issue: [pigeon] Support multiple instances of an API
Labels: package,c: proposal,team-ecosystem,p: pigeon,P3,triaged-ecosystem

<!-- Thank you for using Flutter!

     If you are looking for support, please check out our documentation
     or consider asking a question on Stack Overflow:
      * https://flutter.dev/
      * https://api.flutter.dev/
      * https://stackoverflow.com/questions/tagged/flutter?sort=frequent

     If you have found a bug or if our documentation doesn't have an answer
     to what you're looking for, then fill out the template below. Please read
     our guide to filing a bug first: https://flutter.dev/docs/resources/bug-reports
-->

## Use case

<!--
     Please tell us the problem you are running into that led to you wanting
     a new feature.

     Is your feature request related to a problem? Please give a clear and
     concise description of what the problem is.

     Describe the alternative solutions you've considered. Is there a package
     on pub.dev/flutter that already solves this?
-->

Many plugins allow creating multiple instances of a platform class or resource (e.g. multiple instances of a video player, audio player, etc.) with each maintaining its own state. Currently pigeon allows creating only a single instance of an API, and this forces an instance ID to be passed as an extra parameter on all API calls. This also requires the platform implementation of every method to do a lookup on that ID. The issue with this is more noticeable on plugins that implement a large number of methods, method channels and event channels per instance, but a solution to this problem would benefit plugins on any scale.

In my plugin, I solve this problem by creating separate instances of method channels and event channels for each API instance. It would be useful to support this same solution in pigeon not only because it would be more convenient and more efficient but also because it would allow authors of federated plugins to implement the platform interface in their preferred way right from the beginning. This is important since federated plugins cannot introduce breaking platform interface changes, they must get it right from the beginning.

## Proposal

<!--
     Briefly but precisely describe what you would like Flutter to be able to do.

     Consider attaching images showing what you are imagining.

     Does this have to be provided by Flutter directly, or can it be provided
     by a package on pub.dev/flutter? If so, maybe consider implementing and
     publishing such a package rather than filing a bug.
-->

Allow a method in an API to return an API. For example:

```dart
@HostApi()
abstract class VideoPlayerPluginApi {
  void initialize();
  // This is how the proposed new feature would be introduced:
  VideoPlayerApi create(CreateMessage msg);
}

@HostApi()
abstract class VideoPlayerApi {
  // Note it is no longer necessary to pass the instance id to each of these methods
  void dispose();
  void setLooping(LoopingMessage msg);
  void setVolume(VolumeMessage msg);
  void play();
  PositionMessage position();
  void seekTo(PositionMessage msg);
  void pause();
  void setMixWithOthers(MixWithOthersMessage msg);
}
```

When a new instance is created, pigeon can generate a unique instance ID and add it as a suffix to the method channel name. (It "might" also be necessary to add more annotation data to to let it know that `VideoPlayerPluginApi.create` creates an instance.)

Future versions of pigeon could also allow configuring the method channel name / pattern via the annotation to help plugin developers to maintain backward compatibility in their platform interface.

I have mentioned above that different instances of an API should also be able to maintain different instances event channels. I have submitted a separate proposal to add support for event channels (#66711).

@gaaclarke