private static CallbackResult? InvokeMethod()

in packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/CallbackExtensions.cs [71:147]


        private static CallbackResult? InvokeMethod(InvokeRequest request, IReferenceMap referenceMap)
        {
            request = request ?? throw new ArgumentNullException(nameof(request));
            var deputy = referenceMap.GetOrCreateNativeReference(request.ObjectReference);

            var methodInfo = ReflectionUtils.GetNativeMethod(deputy.GetType(), request.Method);

            if (methodInfo == null)
            {
                throw new InvalidOperationException(
                    $"Received callback for {deputy.GetType().Name}.{request.Method} method, but this method does not exist");
            }

            var attribute = methodInfo.GetAttribute<JsiiMethodAttribute>()!;
            var parameters = methodInfo.GetParameters();

            var converter = ServiceContainer.ServiceProvider.GetRequiredService<IJsiiToFrameworkConverter>();

            var rehydratedArgs = Enumerable.Range(0, request.Arguments?.Length ?? 0)
                .Select(n =>
                {
                    var paramIndex = n >= parameters.Length ? parameters.Length - 1 : n;
                    var requiredType = parameters[paramIndex].ParameterType;
                    if (!converter.TryConvert(attribute.Parameters[paramIndex], requiredType, referenceMap,
                        request.Arguments![n], out var value))
                    {
                        throw new JsiiError($"Unable to convert {request.Arguments![n]} to {requiredType.Name}");
                    }

                    if (attribute.Parameters[paramIndex].IsVariadic)
                    {
                        var array = Array.CreateInstance(value?.GetType() ?? requiredType, 1);
                        array.SetValue(value, 0);
                        value = array;
                    }

                    if (!requiredType.IsInstanceOfType(value) && value is IConvertible)
                    {
                        value = Convert.ChangeType(value, requiredType, CultureInfo.InvariantCulture);
                    }

                    return value;
                }).ToArray();

            var invokeParameters = Enumerable.Range(0, parameters.Length)
                .Select(n =>
                {
                    if (n >= rehydratedArgs.Length)
                    {
                        return null;
                    }

                    if (n == parameters.Length - 1 && rehydratedArgs.Length > parameters.Length)
                    {
                        var allArgs = rehydratedArgs.TakeLast(rehydratedArgs.Length - parameters.Length + 1);
                        var array = Array.CreateInstance(
                            parameters[parameters.Length - 1].ParameterType.GetElementType()!,
                            allArgs.Select(list => (list as Array)!.Length).Sum());
                        var idx = 0;
                        foreach (var list in allArgs)
                        {
                            foreach (var item in (list as Array)!)
                            {
                                array.SetValue(item, idx);
                                idx += 1;
                            }
                        }

                        return array;
                    }

                    return rehydratedArgs[n];
                }).ToArray();

            var returnValue = methodInfo.Invoke(deputy, invokeParameters);
            return attribute?.Returns != null ? new CallbackResult(attribute.Returns, returnValue) : null;
        }