writeFlutterApi method
void
writeFlutterApi(
- JavaOptions generatorOptions,
- Root root,
- Indent indent,
- AstFlutterApi api, {
- required String dartPackageName,
override
Writes the code for a flutter Api, api
.
Example:
public static final class Foo {
public Foo(BinaryMessenger argBinaryMessenger) {...}
public interface Result
Implementation
@override
void writeFlutterApi(
JavaOptions generatorOptions,
Root root,
Indent indent,
AstFlutterApi api, {
required String dartPackageName,
}) {
/// Returns an argument name that can be used in a context where it is possible to collide.
String getSafeArgumentExpression(int count, NamedType argument) {
return '${_getArgumentName(count, argument)}Arg';
}
const List<String> generatedMessages = <String>[
' Generated class from Pigeon that represents Flutter messages that can be called from Java.'
];
addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
generatorComments: generatedMessages);
indent.write('public static class ${api.name} ');
indent.addScoped('{', '}', () {
indent.writeln('private final @NonNull BinaryMessenger binaryMessenger;');
indent.writeln('private final String messageChannelSuffix;');
indent.newln();
indent.write(
'public ${api.name}(@NonNull BinaryMessenger argBinaryMessenger) ');
indent.addScoped('{', '}', () {
indent.writeln('this(argBinaryMessenger, "");');
});
indent.write(
'public ${api.name}(@NonNull BinaryMessenger argBinaryMessenger, @NonNull String messageChannelSuffix) ');
indent.addScoped('{', '}', () {
indent.writeln('this.binaryMessenger = argBinaryMessenger;');
indent.writeln(
'this.messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix;');
});
indent.newln();
addDocumentationComments(indent, <String>[], _docCommentSpec,
generatorComments: <String>[
'Public interface for sending reply.',
'The codec used by ${api.name}.'
]);
indent.write('static @NonNull MessageCodec<Object> getCodec() ');
indent.addScoped('{', '}', () {
indent.writeln('return $_codecName.INSTANCE;');
});
for (final Method func in api.methods) {
final String resultType = _getResultType(func.returnType);
final String returnType = func.returnType.isVoid
? 'Void'
: _javaTypeForDartType(func.returnType);
String sendArgument;
addDocumentationComments(
indent, func.documentationComments, _docCommentSpec);
if (func.parameters.isEmpty) {
indent
.write('public void ${func.name}(@NonNull $resultType result) ');
sendArgument = 'null';
} else {
final Iterable<String> argTypes = func.parameters
.map((NamedType e) => _nullsafeJavaTypeForDartType(e.type));
final Iterable<String> argNames =
indexMap(func.parameters, _getSafeArgumentName);
final Iterable<String> enumSafeArgNames =
indexMap(func.parameters, getSafeArgumentExpression);
if (func.parameters.length == 1) {
sendArgument =
'new ArrayList<>(Collections.singletonList(${enumSafeArgNames.first}))';
} else {
sendArgument =
'new ArrayList<>(Arrays.asList(${enumSafeArgNames.join(', ')}))';
}
final String argsSignature =
map2(argTypes, argNames, (String x, String y) => '$x $y')
.join(', ');
indent.write(
'public void ${func.name}($argsSignature, @NonNull $resultType result) ');
}
indent.addScoped('{', '}', () {
const String channel = 'channel';
indent.writeln(
'final String channelName = "${makeChannelName(api, func, dartPackageName)}" + messageChannelSuffix;');
indent.writeln('BasicMessageChannel<Object> $channel =');
indent.nest(2, () {
indent.writeln('new BasicMessageChannel<>(');
indent.nest(2, () {
indent.writeln('binaryMessenger, channelName, getCodec());');
});
});
indent.writeln('$channel.send(');
indent.nest(2, () {
indent.writeln('$sendArgument,');
indent.write('channelReply -> ');
indent.addScoped('{', '});', () {
indent.writeScoped('if (channelReply instanceof List) {', '} ',
() {
indent.writeln(
'List<Object> listReply = (List<Object>) channelReply;');
indent.writeScoped('if (listReply.size() > 1) {', '} ', () {
indent.writeln(
'result.error(new FlutterError((String) listReply.get(0), (String) listReply.get(1), listReply.get(2)));');
}, addTrailingNewline: false);
if (!func.returnType.isNullable && !func.returnType.isVoid) {
indent.addScoped('else if (listReply.get(0) == null) {', '} ',
() {
indent.writeln(
'result.error(new FlutterError("null-error", "Flutter api returned null value for non-null return value.", ""));');
}, addTrailingNewline: false);
}
indent.addScoped('else {', '}', () {
if (func.returnType.isVoid) {
indent.writeln('result.success();');
} else {
const String output = 'output';
final String outputExpression;
indent.writeln('@SuppressWarnings("ConstantConditions")');
outputExpression =
'${_cast('listReply.get(0)', javaType: returnType)};';
indent.writeln('$returnType $output = $outputExpression');
indent.writeln('result.success($output);');
}
});
}, addTrailingNewline: false);
indent.addScoped(' else {', '} ', () {
indent.writeln(
'result.error(createConnectionError(channelName));');
});
});
});
});
}
});
}