writeFlutterApi method

  1. @override
void writeFlutterApi(
  1. CppOptions generatorOptions,
  2. Root root,
  3. Indent indent,
  4. Api api, {
  5. required String dartPackageName,
})
override

Writes a single Flutter Api to indent.

Implementation

@override
void writeFlutterApi(
  CppOptions generatorOptions,
  Root root,
  Indent indent,
  Api api, {
  required String dartPackageName,
}) {
  assert(api.location == ApiLocation.flutter);
  if (getCodecClasses(api, root).isNotEmpty) {
    _writeCodec(generatorOptions, root, indent, api);
  }
  indent.writeln(
      '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.');
  _writeFunctionDefinition(indent, api.name,
      scope: api.name,
      parameters: <String>['flutter::BinaryMessenger* binary_messenger'],
      initializers: <String>['binary_messenger_(binary_messenger)']);
  final String codeSerializerName = getCodecClasses(api, root).isNotEmpty
      ? _getCodecSerializerName(api)
      : _defaultCodecSerializer;
  _writeFunctionDefinition(indent, 'GetCodec',
      scope: api.name,
      returnType: 'const flutter::StandardMessageCodec&', body: () {
    indent.writeln(
        'return flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance());');
  });
  for (final Method func in api.methods) {
    final String channelName = makeChannelName(api, func, dartPackageName);
    final HostDatatype returnType = getHostDatatype(func.returnType,
        root.classes, root.enums, _shortBaseCppTypeForBuiltinDartType);

    // Determine the input parameter list, saved in a structured form for later
    // use as platform channel call arguments.
    final Iterable<_HostNamedType> hostParameters =
        indexMap(func.arguments, (int i, NamedType arg) {
      final HostDatatype hostType = getFieldHostDatatype(
          arg, root.classes, root.enums, _shortBaseCppTypeForBuiltinDartType);
      return _HostNamedType(_getSafeArgumentName(i, arg), hostType, arg.type);
    });
    final List<String> parameters = <String>[
      ...hostParameters.map((_HostNamedType arg) =>
          '${_flutterApiArgumentType(arg.hostType)} ${arg.name}'),
      ..._flutterApiCallbackParameters(returnType),
    ];
    _writeFunctionDefinition(indent, _makeMethodName(func),
        scope: api.name,
        returnType: _voidType,
        parameters: parameters, body: () {
      const String channel = 'channel';
      indent.writeln(
          'auto channel = std::make_unique<BasicMessageChannel<>>(binary_messenger_, '
          '"$channelName", &GetCodec());');

      // Convert arguments to EncodableValue versions.
      const String argumentListVariableName = 'encoded_api_arguments';
      indent.write('EncodableValue $argumentListVariableName = ');
      if (func.arguments.isEmpty) {
        indent.addln('EncodableValue();');
      } else {
        indent.addScoped('EncodableValue(EncodableList{', '});', () {
          for (final _HostNamedType param in hostParameters) {
            final String encodedArgument = _wrappedHostApiArgumentExpression(
                root, param.name, param.originalType, param.hostType,
                preSerializeClasses: false);
            indent.writeln('$encodedArgument,');
          }
        });
      }

      indent.write('$channel->Send($argumentListVariableName, '
          // ignore: missing_whitespace_between_adjacent_strings
          '[on_success = std::move(on_success), on_error = std::move(on_error)]'
          '(const uint8_t* reply, size_t reply_size) ');
      indent.addScoped('{', '});', () {
        final String successCallbackArgument;
        if (func.returnType.isVoid) {
          successCallbackArgument = '';
        } else {
          successCallbackArgument = 'return_value';
          final String encodedReplyName =
              'encodable_$successCallbackArgument';
          indent.writeln(
              'std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);');
          indent.writeln('const auto& $encodedReplyName = *response;');
          _writeEncodableValueArgumentUnwrapping(
            indent,
            root,
            returnType,
            argName: successCallbackArgument,
            encodableArgName: encodedReplyName,
            apiType: ApiType.flutter,
          );
        }
        indent.writeln('on_success($successCallbackArgument);');
      });
    });
  }
}