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] Moves all codec logic to singular custom codec #6600

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1f2f1f2
add custom codecs
tarrinneal May 6, 2024
932f4f5
fixes bug with headerIncludePath
tarrinneal May 6, 2024
2c80cd7
reorder classes
tarrinneal May 6, 2024
b71a901
Merge branch 'customcodecs' of github.com:tarrinneal/packages into cu…
tarrinneal May 6, 2024
ecb4928
unwrap enums
tarrinneal May 7, 2024
6d69557
wrap case
tarrinneal May 7, 2024
36b86ab
fi unit test
tarrinneal May 8, 2024
f49f1c4
not optional
tarrinneal May 9, 2024
988fad9
comment out failing tests
tarrinneal May 9, 2024
6f78b2f
gen
tarrinneal May 10, 2024
fad35c8
fix kotlin test
tarrinneal May 10, 2024
63f9054
fix c++ and add comments to test files
tarrinneal May 13, 2024
7f47b01
Merge branch 'customcodecs' of github.com:tarrinneal/packages into cu…
tarrinneal May 13, 2024
fa1c0ab
add proxy api changes
tarrinneal May 14, 2024
fea5b9c
fix flutter tests and update generate tool
tarrinneal May 14, 2024
81b0d7d
Merge branch 'main' of github.com:flutter/packages into customcodecs
tarrinneal May 14, 2024
7a050dd
update tools
tarrinneal May 14, 2024
cb64c0a
Merge branch 'main' of github.com:flutter/packages into customcodecs
tarrinneal May 15, 2024
3800d0e
fix unit tests, and re-add enum tests
tarrinneal May 16, 2024
c7b548b
remove extra test classes
tarrinneal May 16, 2024
6fdadac
update version (assuming other pr lands first)
tarrinneal May 16, 2024
22f7c25
Merge branch 'main' of github.com:flutter/packages into customcodecs
tarrinneal May 16, 2024
ed47982
cleanup
tarrinneal May 16, 2024
3dc6c60
remove future work comments
tarrinneal May 16, 2024
eb06884
update error message
tarrinneal May 16, 2024
5c5084b
typo
tarrinneal May 17, 2024
6ddf333
Add test to prevent duplicate entries in Kotlin generator
bc-lee May 18, 2024
7cc9be6
Merge pull request #1 from bc-lee/feature/test-duplicate-entries
tarrinneal May 20, 2024
d16b00b
fix test analyze
tarrinneal May 20, 2024
2c883ca
nits
tarrinneal May 29, 2024
a7113f0
Merge branch 'main' of github.com:flutter/packages into customcodecs
tarrinneal May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -181,7 +181,7 @@ ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<Object>(4);
toListResult.add(name);
toListResult.add(description);
toListResult.add(code == null ? null : code.index);
toListResult.add(code);
toListResult.add(data);
return toListResult;
}
Expand All @@ -193,13 +193,45 @@ ArrayList<Object> toList() {
Object description = __pigeon_list.get(1);
pigeonResult.setDescription((String) description);
Object code = __pigeon_list.get(2);
pigeonResult.setCode(Code.values()[(int) code]);
pigeonResult.setCode((Code) code);
Object data = __pigeon_list.get(3);
pigeonResult.setData((Map<String, String>) data);
return pigeonResult;
}
}

private static class PigeonCodec extends StandardMessageCodec {
public static final PigeonCodec INSTANCE = new PigeonCodec();

private PigeonCodec() {}

@Override
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
switch (type) {
case (byte) 128:
return MessageData.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 129:
Object value = readValue(buffer);
return value == null ? null : Code.values()[(int) value];
default:
return super.readValueOfType(type, buffer);
}
}

@Override
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
if (value instanceof MessageData) {
stream.write(128);
writeValue(stream, ((MessageData) value).toList());
} else if (value instanceof Code) {
stream.write(129);
writeValue(stream, value == null ? null : ((Code) value).index);
} else {
super.writeValue(stream, value);
}
}
}

/** Asynchronous error handling return type for non-nullable API method returns. */
public interface Result<T> {
/** Success case callback method for handling returns. */
Expand All @@ -224,33 +256,6 @@ public interface VoidResult {
/** Failure case callback method for handling errors. */
void error(@NonNull Throwable error);
}

private static class ExampleHostApiCodec extends StandardMessageCodec {
public static final ExampleHostApiCodec INSTANCE = new ExampleHostApiCodec();

private ExampleHostApiCodec() {}

@Override
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
switch (type) {
case (byte) 128:
return MessageData.fromList((ArrayList<Object>) readValue(buffer));
default:
return super.readValueOfType(type, buffer);
}
}

@Override
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
if (value instanceof MessageData) {
stream.write(128);
writeValue(stream, ((MessageData) value).toList());
} else {
super.writeValue(stream, value);
}
}
}

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
public interface ExampleHostApi {

Expand All @@ -264,7 +269,7 @@ public interface ExampleHostApi {

/** The codec used by ExampleHostApi. */
static @NonNull MessageCodec<Object> getCodec() {
return ExampleHostApiCodec.INSTANCE;
return PigeonCodec.INSTANCE;
}
/** Sets up an instance of `ExampleHostApi` to handle messages through the `binaryMessenger`. */
static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable ExampleHostApi api) {
Expand Down Expand Up @@ -382,7 +387,7 @@ public MessageFlutterApi(
/** Public interface for sending reply. */
/** The codec used by MessageFlutterApi. */
static @NonNull MessageCodec<Object> getCodec() {
return new StandardMessageCodec();
return PigeonCodec.INSTANCE;
}

public void flutterMethod(@Nullable String aStringArg, @NonNull Result<String> result) {
Expand Down
Expand Up @@ -69,28 +69,31 @@ data class MessageData(
fun fromList(__pigeon_list: List<Any?>): MessageData {
val name = __pigeon_list[0] as String?
val description = __pigeon_list[1] as String?
val code = Code.ofRaw(__pigeon_list[2] as Int)!!
val code = __pigeon_list[2] as Code
val data = __pigeon_list[3] as Map<String?, String?>
return MessageData(name, description, code, data)
}
}

fun toList(): List<Any?> {
return listOf<Any?>(
return listOf(
name,
description,
code.raw,
code,
data,
)
}
}

private object ExampleHostApiCodec : StandardMessageCodec() {
private object MessagesPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
128.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let { MessageData.fromList(it) }
}
129.toByte() -> {
return (readValue(buffer) as Int?)?.let { Code.ofRaw(it) }
}
else -> super.readValueOfType(type, buffer)
}
}
Expand All @@ -101,6 +104,10 @@ private object ExampleHostApiCodec : StandardMessageCodec() {
stream.write(128)
writeValue(stream, value.toList())
}
is Code -> {
stream.write(129)
writeValue(stream, value.raw)
}
else -> super.writeValue(stream, value)
}
}
Expand All @@ -116,7 +123,7 @@ interface ExampleHostApi {

companion object {
/** The codec used by ExampleHostApi. */
val codec: MessageCodec<Any?> by lazy { ExampleHostApiCodec }
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec }
/** Sets up an instance of `ExampleHostApi` to handle messages through the `binaryMessenger`. */
fun setUp(
binaryMessenger: BinaryMessenger,
Expand All @@ -135,7 +142,7 @@ interface ExampleHostApi {
channel.setMessageHandler { _, reply ->
val wrapped: List<Any?> =
try {
listOf<Any?>(api.getHostLanguage())
listOf(api.getHostLanguage())
} catch (exception: Throwable) {
wrapError(exception)
}
Expand All @@ -158,7 +165,7 @@ interface ExampleHostApi {
val bArg = args[1].let { num -> if (num is Int) num.toLong() else num as Long }
val wrapped: List<Any?> =
try {
listOf<Any?>(api.add(aArg, bArg))
listOf(api.add(aArg, bArg))
} catch (exception: Throwable) {
wrapError(exception)
}
Expand Down Expand Up @@ -202,7 +209,7 @@ class MessageFlutterApi(
) {
companion object {
/** The codec used by MessageFlutterApi. */
val codec: MessageCodec<Any?> by lazy { StandardMessageCodec() }
val codec: MessageCodec<Any?> by lazy { MessagesPigeonCodec }
}

fun flutterMethod(aStringArg: String?, callback: (Result<String>) -> Unit) {
Expand Down
38 changes: 25 additions & 13 deletions packages/pigeon/example/app/ios/Runner/Messages.g.swift
Expand Up @@ -64,7 +64,7 @@ struct MessageData {
static func fromList(_ __pigeon_list: [Any?]) -> MessageData? {
let name: String? = nilOrValue(__pigeon_list[0])
let description: String? = nilOrValue(__pigeon_list[1])
let code = Code(rawValue: __pigeon_list[2] as! Int)!
let code = __pigeon_list[2] as! Code
let data = __pigeon_list[3] as! [String?: String?]

return MessageData(
Expand All @@ -78,46 +78,55 @@ struct MessageData {
return [
name,
description,
code.rawValue,
code,
data,
]
}
}

private class ExampleHostApiCodecReader: FlutterStandardReader {
private class MessagesPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 128:
return MessageData.fromList(self.readValue() as! [Any?])
case 129:
var enumResult: Code? = nil
let enumResultAsInt: Int? = nilOrValue(self.readValue() as? Int)
if let enumResultAsInt = enumResultAsInt {
enumResult = Code(rawValue: enumResultAsInt)
}
return enumResult
default:
return super.readValue(ofType: type)
}
}
}

private class ExampleHostApiCodecWriter: FlutterStandardWriter {
private class MessagesPigeonCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? MessageData {
super.writeByte(128)
super.writeValue(value.toList())
} else if let value = value as? Code {
super.writeByte(129)
super.writeValue(value.rawValue)
} else {
super.writeValue(value)
}
}
}

private class ExampleHostApiCodecReaderWriter: FlutterStandardReaderWriter {
private class MessagesPigeonCodecReaderWriter: FlutterStandardReaderWriter {
override func reader(with data: Data) -> FlutterStandardReader {
return ExampleHostApiCodecReader(data: data)
return MessagesPigeonCodecReader(data: data)
}

override func writer(with data: NSMutableData) -> FlutterStandardWriter {
return ExampleHostApiCodecWriter(data: data)
return MessagesPigeonCodecWriter(data: data)
}
}

class ExampleHostApiCodec: FlutterStandardMessageCodec {
static let shared = ExampleHostApiCodec(readerWriter: ExampleHostApiCodecReaderWriter())
class MessagesPigeonCodec: FlutterStandardMessageCodec {
static let shared = MessagesPigeonCodec(readerWriter: MessagesPigeonCodecReaderWriter())
}

/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
Expand All @@ -129,8 +138,7 @@ protocol ExampleHostApi {

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class ExampleHostApiSetup {
/// The codec used by ExampleHostApi.
static var codec: FlutterStandardMessageCodec { ExampleHostApiCodec.shared }
static var codec: FlutterStandardMessageCodec { MessagesPigeonCodec.shared }
/// Sets up an instance of `ExampleHostApi` to handle messages through the `binaryMessenger`.
static func setUp(
binaryMessenger: FlutterBinaryMessenger, api: ExampleHostApi?, messageChannelSuffix: String = ""
Expand Down Expand Up @@ -203,12 +211,16 @@ class MessageFlutterApi: MessageFlutterApiProtocol {
self.binaryMessenger = binaryMessenger
self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
}
var codec: MessagesPigeonCodec {
return MessagesPigeonCodec.shared
}
func flutterMethod(
aString aStringArg: String?, completion: @escaping (Result<String, FlutterError>) -> Void
) {
let channelName: String =
"dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod\(messageChannelSuffix)"
let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger)
let channel = FlutterBasicMessageChannel(
name: channelName, binaryMessenger: binaryMessenger, codec: codec)
channel.sendMessage([aStringArg] as [Any?]) { response in
guard let listResponse = response as? [Any?] else {
completion(.failure(createConnectionError(withChannelName: channelName)))
Expand Down
20 changes: 12 additions & 8 deletions packages/pigeon/example/app/lib/src/messages.g.dart
Expand Up @@ -54,7 +54,7 @@ class MessageData {
return <Object?>[
name,
description,
code.index,
code,
data,
];
}
Expand All @@ -64,19 +64,22 @@ class MessageData {
return MessageData(
name: result[0] as String?,
description: result[1] as String?,
code: Code.values[result[2]! as int],
code: result[2]! as Code,
data: (result[3] as Map<Object?, Object?>?)!.cast<String?, String?>(),
);
}
}

class _ExampleHostApiCodec extends StandardMessageCodec {
const _ExampleHostApiCodec();
class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is MessageData) {
buffer.putUint8(128);
writeValue(buffer, value.encode());
} else if (value is Code) {
buffer.putUint8(129);
writeValue(buffer, value.index);
} else {
super.writeValue(buffer, value);
}
Expand All @@ -87,6 +90,9 @@ class _ExampleHostApiCodec extends StandardMessageCodec {
switch (type) {
case 128:
return MessageData.decode(readValue(buffer)!);
case 129:
final int? value = readValue(buffer) as int?;
return value == null ? null : Code.values[value];
default:
return super.readValueOfType(type, buffer);
}
Expand All @@ -104,8 +110,7 @@ class ExampleHostApi {
messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
final BinaryMessenger? __pigeon_binaryMessenger;

static const MessageCodec<Object?> pigeonChannelCodec =
_ExampleHostApiCodec();
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

final String __pigeon_messageChannelSuffix;

Expand Down Expand Up @@ -198,8 +203,7 @@ class ExampleHostApi {
}

abstract class MessageFlutterApi {
static const MessageCodec<Object?> pigeonChannelCodec =
StandardMessageCodec();
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

String flutterMethod(String? aString);

Expand Down
7 changes: 2 additions & 5 deletions packages/pigeon/example/app/macos/Runner/messages.g.h
Expand Up @@ -39,8 +39,8 @@ typedef NS_ENUM(NSUInteger, PGNCode) {
@property(nonatomic, copy) NSDictionary<NSString *, NSString *> *data;
@end

/// The codec used by PGNExampleHostApi.
NSObject<FlutterMessageCodec> *PGNExampleHostApiGetCodec(void);
/// The codec used by all APIs.
NSObject<FlutterMessageCodec> *PGNmessagesGetCodec(void);
tarrinneal marked this conversation as resolved.
Show resolved Hide resolved

@protocol PGNExampleHostApi
/// @return `nil` only when `error != nil`.
Expand All @@ -60,9 +60,6 @@ extern void SetUpPGNExampleHostApiWithSuffix(id<FlutterBinaryMessenger> binaryMe
NSObject<PGNExampleHostApi> *_Nullable api,
NSString *messageChannelSuffix);

/// The codec used by PGNMessageFlutterApi.
NSObject<FlutterMessageCodec> *PGNMessageFlutterApiGetCodec(void);

@interface PGNMessageFlutterApi : NSObject
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger
Expand Down