Search in sources :

Example 1 with Recorder

use of io.quarkus.runtime.annotations.Recorder in project quarkus by quarkusio.

the class ExtensionLoader method loadStepsFrom.

/**
 * Load all the build steps from the given class loader.
 *
 * @param classLoader the class loader
 * @param buildSystemProps the build system properties to use
 * @param launchMode launch mode
 * @param configCustomizer configuration customizer
 * @return a consumer which adds the steps to the given chain builder
 * @throws IOException if the class loader could not load a resource
 * @throws ClassNotFoundException if a build step class is not found
 */
public static Consumer<BuildChainBuilder> loadStepsFrom(ClassLoader classLoader, Properties buildSystemProps, ApplicationModel appModel, LaunchMode launchMode, DevModeType devModeType) throws IOException, ClassNotFoundException {
    // populate with all known types
    List<Class<?>> roots = new ArrayList<>();
    for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
        final ConfigRoot annotation = clazz.getAnnotation(ConfigRoot.class);
        if (annotation == null) {
            cfgLog.warnf("Ignoring configuration root %s because it has no annotation", clazz);
        } else {
            roots.add(clazz);
        }
    }
    final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(roots);
    // now prepare & load the build configuration
    final SmallRyeConfigBuilder builder = ConfigUtils.configBuilder(false, launchMode);
    final DefaultValuesConfigurationSource ds1 = new DefaultValuesConfigurationSource(reader.getBuildTimePatternMap());
    final DefaultValuesConfigurationSource ds2 = new DefaultValuesConfigurationSource(reader.getBuildTimeRunTimePatternMap());
    final PropertiesConfigSource pcs = new PropertiesConfigSource(buildSystemProps, "Build system");
    final Map<String, String> platformProperties = appModel.getPlatformProperties();
    if (platformProperties.isEmpty()) {
        builder.withSources(ds1, ds2, pcs);
    } else {
        final KeyMap<String> props = new KeyMap<>(platformProperties.size());
        for (Map.Entry<String, String> prop : platformProperties.entrySet()) {
            props.findOrAdd(new NameIterator(prop.getKey())).putRootValue(prop.getValue());
        }
        final KeyMapBackedConfigSource platformConfigSource = new KeyMapBackedConfigSource("Quarkus platform", // (see io.quarkus.deployment.configuration.DefaultValuesConfigurationSource)
        Integer.MIN_VALUE + 1000, props);
        builder.withSources(ds1, ds2, platformConfigSource, pcs);
    }
    for (ConfigClassWithPrefix mapping : reader.getBuildTimeVisibleMappings()) {
        builder.withMapping(mapping.getKlass(), mapping.getPrefix());
    }
    final SmallRyeConfig src = builder.build();
    // install globally
    QuarkusConfigFactory.setConfig(src);
    final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
    try {
        cpr.releaseConfig(cpr.getConfig());
    } catch (IllegalStateException ignored) {
    // just means no config was installed, which is fine
    }
    final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src);
    final BooleanSupplierFactoryBuildItem bsf = new BooleanSupplierFactoryBuildItem(readResult, launchMode, devModeType);
    Consumer<BuildChainBuilder> result = Functions.discardingConsumer();
    // BooleanSupplier factory
    result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
        bc.produce(bsf);
    }).produces(BooleanSupplierFactoryBuildItem.class).build());
    // the proxy objects used for run time config in the recorders
    Map<Class<?>, Object> proxies = new HashMap<>();
    for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, "META-INF/quarkus-build-steps.list")) {
        try {
            result = result.andThen(ExtensionLoader.loadStepsFromClass(clazz, readResult, proxies, bsf));
        } catch (Throwable e) {
            throw new RuntimeException("Failed to load steps from " + clazz, e);
        }
    }
    // this has to be an identity hash map else the recorder will get angry
    Map<Object, FieldDescriptor> rootFields = new IdentityHashMap<>();
    Map<Object, ConfigClassWithPrefix> mappingClasses = new IdentityHashMap<>();
    for (Map.Entry<Class<?>, Object> entry : proxies.entrySet()) {
        // ConfigRoot
        RootDefinition root = readResult.getAllRootsByClass().get(entry.getKey());
        if (root != null) {
            rootFields.put(entry.getValue(), root.getDescriptor());
            continue;
        }
        // ConfigMapping
        ConfigClassWithPrefix mapping = readResult.getAllMappings().get(entry.getKey());
        if (mapping != null) {
            mappingClasses.put(entry.getValue(), mapping);
            continue;
        }
        throw new IllegalStateException("No config found for " + entry.getKey());
    }
    result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
        bc.produce(new ConfigurationBuildItem(readResult));
        bc.produce(new RunTimeConfigurationProxyBuildItem(proxies));
        ObjectLoader rootLoader = new ObjectLoader() {

            public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
                return body.readStaticField(rootFields.get(obj));
            }

            public boolean canHandleObject(final Object obj, final boolean staticInit) {
                return rootFields.containsKey(obj);
            }
        };
        ObjectLoader mappingLoader = new ObjectLoader() {

            @Override
            public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
                ConfigClassWithPrefix mapping = mappingClasses.get(obj);
                MethodDescriptor getConfig = MethodDescriptor.ofMethod(ConfigProvider.class, "getConfig", Config.class);
                ResultHandle config = body.invokeStaticMethod(getConfig);
                MethodDescriptor getMapping = MethodDescriptor.ofMethod(SmallRyeConfig.class, "getConfigMapping", Object.class, Class.class, String.class);
                return body.invokeVirtualMethod(getMapping, config, body.loadClass(mapping.getKlass()), body.load(mapping.getPrefix()));
            }

            @Override
            public boolean canHandleObject(final Object obj, final boolean staticInit) {
                return mappingClasses.containsKey(obj);
            }
        };
        bc.produce(new BytecodeRecorderObjectLoaderBuildItem(rootLoader));
        bc.produce(new BytecodeRecorderObjectLoaderBuildItem(mappingLoader));
    }).produces(ConfigurationBuildItem.class).produces(RunTimeConfigurationProxyBuildItem.class).produces(BytecodeRecorderObjectLoaderBuildItem.class).build());
    return result;
}
Also used : RootDefinition(io.quarkus.deployment.configuration.definition.RootDefinition) ReflectUtil.isSupplierOfOptionalOf(io.quarkus.deployment.util.ReflectUtil.isSupplierOfOptionalOf) RecorderContext(io.quarkus.deployment.recording.RecorderContext) BooleanSupplier(java.util.function.BooleanSupplier) Functions(org.wildfly.common.function.Functions) ReflectUtil.isSupplierOf(io.quarkus.deployment.util.ReflectUtil.isSupplierOf) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) BytecodeCreator(io.quarkus.gizmo.BytecodeCreator) Recorder(io.quarkus.runtime.annotations.Recorder) ConsumeFlags(io.quarkus.builder.ConsumeFlags) RunTimeConfigurationProxyBuildItem(io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem) ReflectUtil.rawTypeIs(io.quarkus.deployment.util.ReflectUtil.rawTypeIs) KeyMap(io.smallrye.config.KeyMap) EnumSet(java.util.EnumSet) Consume(io.quarkus.deployment.annotations.Consume) Member(java.lang.reflect.Member) MainBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.MainBytecodeRecorderBuildItem) StaticBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.StaticBytecodeRecorderBuildItem) ReflectUtil.isBuildProducerOf(io.quarkus.deployment.util.ReflectUtil.isBuildProducerOf) InvocationTargetException(java.lang.reflect.InvocationTargetException) Weak(io.quarkus.deployment.annotations.Weak) ApplicationModel(io.quarkus.bootstrap.model.ApplicationModel) ConfigProvider(org.eclipse.microprofile.config.ConfigProvider) ConsumeFlag(io.quarkus.builder.ConsumeFlag) PropertiesConfigSource(io.smallrye.config.PropertiesConfigSource) ConfigClassWithPrefix(io.smallrye.config.ConfigMappings.ConfigClassWithPrefix) ResultHandle(io.quarkus.gizmo.ResultHandle) AnnotatedElement(java.lang.reflect.AnnotatedElement) Record(io.quarkus.deployment.annotations.Record) ProduceWeak(io.quarkus.deployment.annotations.ProduceWeak) DevModeType(io.quarkus.dev.spi.DevModeType) ReflectUtil.rawTypeOf(io.quarkus.deployment.util.ReflectUtil.rawTypeOf) BuildStepBuilder(io.quarkus.builder.BuildStepBuilder) BuildItem(io.quarkus.builder.item.BuildItem) SimpleBuildItem(io.quarkus.builder.item.SimpleBuildItem) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ConfigRoot(io.quarkus.runtime.annotations.ConfigRoot) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) Parameter(java.lang.reflect.Parameter) BiConsumer(java.util.function.BiConsumer) KeyMapBackedConfigSource(io.smallrye.config.KeyMapBackedConfigSource) Properties(java.util.Properties) Executor(java.util.concurrent.Executor) IOException(java.io.IOException) Field(java.lang.reflect.Field) FieldDescriptor(io.quarkus.gizmo.FieldDescriptor) ParameterizedType(java.lang.reflect.ParameterizedType) SmallRyeConfigBuilder(io.smallrye.config.SmallRyeConfigBuilder) ConfigPhase(io.quarkus.runtime.annotations.ConfigPhase) BiFunction(java.util.function.BiFunction) ProduceFlags(io.quarkus.builder.ProduceFlags) Overridable(io.quarkus.deployment.annotations.Overridable) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) ConfigProviderResolver(org.eclipse.microprofile.config.spi.ConfigProviderResolver) ProduceFlag(io.quarkus.builder.ProduceFlag) ReflectUtil(io.quarkus.deployment.util.ReflectUtil) Method(java.lang.reflect.Method) BootstrapConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem) IdentityHashMap(java.util.IdentityHashMap) ReflectUtil.isOptionalOf(io.quarkus.deployment.util.ReflectUtil.isOptionalOf) ReflectUtil.rawTypeExtends(io.quarkus.deployment.util.ReflectUtil.rawTypeExtends) ExecutionTime(io.quarkus.deployment.annotations.ExecutionTime) Config(org.eclipse.microprofile.config.Config) DefaultValuesConfigurationSource(io.quarkus.deployment.configuration.DefaultValuesConfigurationSource) List(java.util.List) BuildContext(io.quarkus.builder.BuildContext) Type(java.lang.reflect.Type) Modifier(java.lang.reflect.Modifier) Optional(java.util.Optional) ConfigMappingUtils(io.quarkus.deployment.configuration.ConfigMappingUtils) ConfigUtils(io.quarkus.runtime.configuration.ConfigUtils) Logger(org.jboss.logging.Logger) LaunchMode(io.quarkus.runtime.LaunchMode) HashMap(java.util.HashMap) Function(java.util.function.Function) ReflectUtil.isConsumerOf(io.quarkus.deployment.util.ReflectUtil.isConsumerOf) Inject(javax.inject.Inject) ConfigurationBuildItem(io.quarkus.deployment.builditem.ConfigurationBuildItem) BuildStep(io.quarkus.deployment.annotations.BuildStep) ReflectUtil.isListOf(io.quarkus.deployment.util.ReflectUtil.isListOf) RuntimeValue(io.quarkus.runtime.RuntimeValue) RuntimeConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem) ObjectLoader(io.quarkus.deployment.recording.ObjectLoader) QuarkusConfigFactory(io.quarkus.runtime.configuration.QuarkusConfigFactory) BytecodeRecorderObjectLoaderBuildItem(io.quarkus.deployment.builditem.BytecodeRecorderObjectLoaderBuildItem) MethodDescriptor(io.quarkus.gizmo.MethodDescriptor) SmallRyeConfig(io.smallrye.config.SmallRyeConfig) BuildTimeConfigurationReader(io.quarkus.deployment.configuration.BuildTimeConfigurationReader) Produce(io.quarkus.deployment.annotations.Produce) Consumer(java.util.function.Consumer) MultiBuildItem(io.quarkus.builder.item.MultiBuildItem) NameIterator(io.smallrye.config.NameIterator) ReflectUtil.rawTypeOfParameter(io.quarkus.deployment.util.ReflectUtil.rawTypeOfParameter) ServiceUtil(io.quarkus.deployment.util.ServiceUtil) BytecodeRecorderImpl(io.quarkus.deployment.recording.BytecodeRecorderImpl) Collections(java.util.Collections) PropertiesConfigSource(io.smallrye.config.PropertiesConfigSource) ConfigRoot(io.quarkus.runtime.annotations.ConfigRoot) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) DefaultValuesConfigurationSource(io.quarkus.deployment.configuration.DefaultValuesConfigurationSource) IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) BuildTimeConfigurationReader(io.quarkus.deployment.configuration.BuildTimeConfigurationReader) FieldDescriptor(io.quarkus.gizmo.FieldDescriptor) SmallRyeConfigBuilder(io.smallrye.config.SmallRyeConfigBuilder) NameIterator(io.smallrye.config.NameIterator) ResultHandle(io.quarkus.gizmo.ResultHandle) ConfigurationBuildItem(io.quarkus.deployment.builditem.ConfigurationBuildItem) KeyMap(io.smallrye.config.KeyMap) RootDefinition(io.quarkus.deployment.configuration.definition.RootDefinition) ConfigClassWithPrefix(io.smallrye.config.ConfigMappings.ConfigClassWithPrefix) BytecodeCreator(io.quarkus.gizmo.BytecodeCreator) MethodDescriptor(io.quarkus.gizmo.MethodDescriptor) KeyMapBackedConfigSource(io.smallrye.config.KeyMapBackedConfigSource) SmallRyeConfig(io.smallrye.config.SmallRyeConfig) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) RunTimeConfigurationProxyBuildItem(io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem) ConfigProviderResolver(org.eclipse.microprofile.config.spi.ConfigProviderResolver) BytecodeRecorderObjectLoaderBuildItem(io.quarkus.deployment.builditem.BytecodeRecorderObjectLoaderBuildItem) ObjectLoader(io.quarkus.deployment.recording.ObjectLoader) Map(java.util.Map) KeyMap(io.smallrye.config.KeyMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap)

Example 2 with Recorder

use of io.quarkus.runtime.annotations.Recorder in project quarkus by quarkusio.

the class ExtensionLoader method loadStepsFromClass.

/**
 * Load all the build steps from the given class.
 *
 * @param clazz the class to load from (must not be {@code null})
 * @param readResult the build time configuration read result (must not be {@code null})
 * @param runTimeProxies the map of run time proxy objects to populate for recorders (must not be {@code null})
 * @return a consumer which adds the steps to the given chain builder
 */
private static Consumer<BuildChainBuilder> loadStepsFromClass(Class<?> clazz, BuildTimeConfigurationReader.ReadResult readResult, Map<Class<?>, Object> runTimeProxies, BooleanSupplierFactoryBuildItem supplierFactory) {
    final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
    // this is the chain configuration that will contain all steps on this class and be returned
    Consumer<BuildChainBuilder> chainConfig = Functions.discardingConsumer();
    if (Modifier.isAbstract(clazz.getModifiers())) {
        return chainConfig;
    }
    // this is the step configuration that applies to all steps on this class
    Consumer<BuildStepBuilder> stepConfig = Functions.discardingConsumer();
    // this is the build step instance setup that applies to all steps on this class
    BiConsumer<BuildContext, Object> stepInstanceSetup = Functions.discardingBiConsumer();
    if (constructors.length != 1) {
        throw reportError(clazz, "Build step classes must have exactly one constructor");
    }
    EnumSet<ConfigPhase> consumingConfigPhases = EnumSet.noneOf(ConfigPhase.class);
    final Constructor<?> constructor = constructors[0];
    if (!(Modifier.isPublic(constructor.getModifiers())))
        constructor.setAccessible(true);
    final Parameter[] ctorParameters = constructor.getParameters();
    final List<Function<BuildContext, Object>> ctorParamFns;
    if (ctorParameters.length == 0) {
        ctorParamFns = Collections.emptyList();
    } else {
        ctorParamFns = new ArrayList<>(ctorParameters.length);
        for (Parameter parameter : ctorParameters) {
            Type parameterType = parameter.getParameterizedType();
            final Class<?> parameterClass = parameter.getType();
            final boolean weak = parameter.isAnnotationPresent(Weak.class);
            final boolean overridable = parameter.isAnnotationPresent(Overridable.class);
            if (rawTypeExtends(parameterType, SimpleBuildItem.class)) {
                final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOf(parameterType).asSubclass(SimpleBuildItem.class);
                stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                ctorParamFns.add(bc -> bc.consume(buildItemClass));
            } else if (isListOf(parameterType, MultiBuildItem.class)) {
                final Class<? extends MultiBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(MultiBuildItem.class);
                stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                ctorParamFns.add(bc -> bc.consumeMulti(buildItemClass));
            } else if (isConsumerOf(parameterType, BuildItem.class)) {
                deprecatedProducer(parameter);
                final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(BuildItem.class);
                if (overridable) {
                    if (weak) {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                    } else {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                    }
                } else {
                    if (weak) {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                    } else {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                    }
                }
                ctorParamFns.add(bc -> (Consumer<? extends BuildItem>) bc::produce);
            } else if (isBuildProducerOf(parameterType, BuildItem.class)) {
                deprecatedProducer(parameter);
                final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(BuildItem.class);
                if (overridable) {
                    if (weak) {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                    } else {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                    }
                } else {
                    if (weak) {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                    } else {
                        stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                    }
                }
                ctorParamFns.add(bc -> (BuildProducer<? extends BuildItem>) bc::produce);
            } else if (isOptionalOf(parameterType, SimpleBuildItem.class)) {
                final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(SimpleBuildItem.class);
                stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
                ctorParamFns.add(bc -> Optional.ofNullable(bc.consume(buildItemClass)));
            } else if (isSupplierOf(parameterType, SimpleBuildItem.class)) {
                final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(SimpleBuildItem.class);
                stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                ctorParamFns.add(bc -> (Supplier<? extends SimpleBuildItem>) () -> bc.consume(buildItemClass));
            } else if (isSupplierOfOptionalOf(parameterType, SimpleBuildItem.class)) {
                final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(rawTypeOfParameter(parameterType, 0), 0).asSubclass(SimpleBuildItem.class);
                stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
                ctorParamFns.add(bc -> (Supplier<Optional<? extends SimpleBuildItem>>) () -> Optional.ofNullable(bc.consume(buildItemClass)));
            } else if (rawTypeOf(parameterType) == Executor.class) {
                ctorParamFns.add(BuildContext::getExecutor);
            } else if (parameterClass.isAnnotationPresent(ConfigRoot.class)) {
                final ConfigRoot annotation = parameterClass.getAnnotation(ConfigRoot.class);
                final ConfigPhase phase = annotation.phase();
                consumingConfigPhases.add(phase);
                if (phase.isAvailableAtBuild()) {
                    ctorParamFns.add(bc -> bc.consume(ConfigurationBuildItem.class).getReadResult().requireObjectForClass(parameterClass));
                    if (phase == ConfigPhase.BUILD_AND_RUN_TIME_FIXED) {
                        runTimeProxies.computeIfAbsent(parameterClass, readResult::requireObjectForClass);
                    }
                } else if (phase.isReadAtMain()) {
                    throw reportError(parameter, phase + " configuration cannot be consumed here");
                } else {
                    throw reportError(parameterClass, "Unknown value for ConfigPhase");
                }
            } else if (isRecorder(parameterClass)) {
                throw reportError(parameter, "Bytecode recorders disallowed on constructor parameters");
            } else {
                throw reportError(parameter, "Unsupported constructor parameter type " + parameterType);
            }
        }
    }
    // index fields
    final Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        final int mods = field.getModifiers();
        if (Modifier.isStatic(mods)) {
            // ignore static fields
            continue;
        }
        if (Modifier.isFinal(mods)) {
            // ignore final fields
            continue;
        }
        if (!Modifier.isPublic(mods) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
            field.setAccessible(true);
        }
        // next, determine the type
        final Type fieldType = field.getGenericType();
        final Class<?> fieldClass = field.getType();
        final boolean weak = field.isAnnotationPresent(Weak.class);
        final boolean overridable = field.isAnnotationPresent(Overridable.class);
        if (rawTypeExtends(fieldType, SimpleBuildItem.class)) {
            final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOf(fieldType).asSubclass(SimpleBuildItem.class);
            stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, bc.consume(buildItemClass)));
        } else if (isListOf(fieldType, MultiBuildItem.class)) {
            final Class<? extends MultiBuildItem> buildItemClass = rawTypeOfParameter(fieldType, 0).asSubclass(MultiBuildItem.class);
            stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, bc.consumeMulti(buildItemClass)));
        } else if (isConsumerOf(fieldType, BuildItem.class)) {
            deprecatedProducer(field);
            final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(fieldType, 0).asSubclass(BuildItem.class);
            if (overridable) {
                if (weak) {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                } else {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                }
            } else {
                if (weak) {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                } else {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                }
            }
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, (Consumer<? extends BuildItem>) bc::produce));
        } else if (isBuildProducerOf(fieldType, BuildItem.class)) {
            deprecatedProducer(field);
            final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(fieldType, 0).asSubclass(BuildItem.class);
            if (overridable) {
                if (weak) {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                } else {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                }
            } else {
                if (weak) {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                } else {
                    stepConfig = stepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                }
            }
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, (BuildProducer<? extends BuildItem>) bc::produce));
        } else if (isOptionalOf(fieldType, SimpleBuildItem.class)) {
            final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(fieldType, 0).asSubclass(SimpleBuildItem.class);
            stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, Optional.ofNullable(bc.consume(buildItemClass))));
        } else if (isSupplierOf(fieldType, SimpleBuildItem.class)) {
            final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(fieldType, 0).asSubclass(SimpleBuildItem.class);
            stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, (Supplier<? extends SimpleBuildItem>) () -> bc.consume(buildItemClass)));
        } else if (isSupplierOfOptionalOf(fieldType, SimpleBuildItem.class)) {
            final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(rawTypeOfParameter(fieldType, 0), 0).asSubclass(SimpleBuildItem.class);
            stepConfig = stepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, (Supplier<Optional<? extends SimpleBuildItem>>) () -> Optional.ofNullable(bc.consume(buildItemClass))));
        } else if (fieldClass == Executor.class) {
            stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> ReflectUtil.setFieldVal(field, o, bc.getExecutor()));
        } else if (fieldClass.isAnnotationPresent(ConfigRoot.class)) {
            final ConfigRoot annotation = fieldClass.getAnnotation(ConfigRoot.class);
            final ConfigPhase phase = annotation.phase();
            consumingConfigPhases.add(phase);
            if (phase.isAvailableAtBuild()) {
                stepInstanceSetup = stepInstanceSetup.andThen((bc, o) -> {
                    final ConfigurationBuildItem configurationBuildItem = bc.consume(ConfigurationBuildItem.class);
                    ReflectUtil.setFieldVal(field, o, configurationBuildItem.getReadResult().requireObjectForClass(fieldClass));
                });
                if (phase == ConfigPhase.BUILD_AND_RUN_TIME_FIXED) {
                    runTimeProxies.computeIfAbsent(fieldClass, readResult::requireObjectForClass);
                }
            } else if (phase.isReadAtMain()) {
                throw reportError(field, phase + " configuration cannot be consumed here");
            } else {
                throw reportError(fieldClass, "Unknown value for ConfigPhase");
            }
        } else if (isRecorder(fieldClass)) {
            throw reportError(field, "Bytecode recorders disallowed on fields");
        } else {
            throw reportError(field, "Unsupported field type " + fieldType);
        }
    }
    // now iterate the methods
    final List<Method> methods = getMethods(clazz);
    for (Method method : methods) {
        final BuildStep buildStep = method.getAnnotation(BuildStep.class);
        if (buildStep == null) {
            continue;
        }
        if (Modifier.isStatic(method.getModifiers())) {
            throw new RuntimeException("A build step must be a non-static method: " + method);
        }
        if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
            method.setAccessible(true);
        }
        final Class<? extends BooleanSupplier>[] onlyIf = buildStep.onlyIf();
        final Class<? extends BooleanSupplier>[] onlyIfNot = buildStep.onlyIfNot();
        final Parameter[] methodParameters = method.getParameters();
        final Record recordAnnotation = method.getAnnotation(Record.class);
        final boolean isRecorder = recordAnnotation != null;
        final boolean identityComparison = isRecorder ? recordAnnotation.useIdentityComparisonForParameters() : true;
        if (isRecorder) {
            boolean recorderFound = false;
            for (Class<?> p : method.getParameterTypes()) {
                if (isRecorder(p)) {
                    recorderFound = true;
                    break;
                }
            }
            if (!recorderFound) {
                throw new RuntimeException(method + " is marked @Record but does not inject an @Recorder object");
            }
        }
        final List<BiFunction<BuildContext, BytecodeRecorderImpl, Object>> methodParamFns;
        Consumer<BuildStepBuilder> methodStepConfig = Functions.discardingConsumer();
        BooleanSupplier addStep = () -> true;
        for (boolean inv : new boolean[] { false, true }) {
            Class<? extends BooleanSupplier>[] testClasses = inv ? onlyIfNot : onlyIf;
            for (Class<? extends BooleanSupplier> testClass : testClasses) {
                BooleanSupplier bs = supplierFactory.get((Class<? extends BooleanSupplier>) testClass);
                if (inv) {
                    addStep = and(addStep, not(bs));
                } else {
                    addStep = and(addStep, bs);
                }
            }
        }
        final BooleanSupplier finalAddStep = addStep;
        if (isRecorder) {
            assert recordAnnotation != null;
            final ExecutionTime executionTime = recordAnnotation.value();
            final boolean optional = recordAnnotation.optional();
            methodStepConfig = methodStepConfig.andThen(bsb -> {
                bsb.produces(executionTime == ExecutionTime.STATIC_INIT ? StaticBytecodeRecorderBuildItem.class : MainBytecodeRecorderBuildItem.class, optional ? ProduceFlags.of(ProduceFlag.WEAK) : ProduceFlags.NONE);
            });
        }
        EnumSet<ConfigPhase> methodConsumingConfigPhases = consumingConfigPhases.clone();
        if (methodParameters.length == 0) {
            methodParamFns = Collections.emptyList();
        } else {
            methodParamFns = new ArrayList<>(methodParameters.length);
            for (Parameter parameter : methodParameters) {
                final boolean weak = parameter.isAnnotationPresent(Weak.class);
                final boolean overridable = parameter.isAnnotationPresent(Overridable.class);
                final Type parameterType = parameter.getParameterizedType();
                final Class<?> parameterClass = parameter.getType();
                if (rawTypeExtends(parameterType, SimpleBuildItem.class)) {
                    final Class<? extends SimpleBuildItem> buildItemClass = parameterClass.asSubclass(SimpleBuildItem.class);
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                    methodParamFns.add((bc, bri) -> bc.consume(buildItemClass));
                } else if (isListOf(parameterType, MultiBuildItem.class)) {
                    final Class<? extends MultiBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(MultiBuildItem.class);
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                    methodParamFns.add((bc, bri) -> bc.consumeMulti(buildItemClass));
                } else if (isConsumerOf(parameterType, BuildItem.class)) {
                    final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(BuildItem.class);
                    if (overridable) {
                        if (weak) {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                        } else {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                        }
                    } else {
                        if (weak) {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                        } else {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                        }
                    }
                    methodParamFns.add((bc, bri) -> (Consumer<? extends BuildItem>) bc::produce);
                } else if (isBuildProducerOf(parameterType, BuildItem.class)) {
                    final Class<? extends BuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(BuildItem.class);
                    if (overridable) {
                        if (weak) {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                        } else {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.OVERRIDABLE));
                        }
                    } else {
                        if (weak) {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass, ProduceFlag.WEAK));
                        } else {
                            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(buildItemClass));
                        }
                    }
                    methodParamFns.add((bc, bri) -> (BuildProducer<? extends BuildItem>) bc::produce);
                } else if (isOptionalOf(parameterType, SimpleBuildItem.class)) {
                    final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(SimpleBuildItem.class);
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
                    methodParamFns.add((bc, bri) -> Optional.ofNullable(bc.consume(buildItemClass)));
                } else if (isSupplierOf(parameterType, SimpleBuildItem.class)) {
                    final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(parameterType, 0).asSubclass(SimpleBuildItem.class);
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(buildItemClass));
                    methodParamFns.add((bc, bri) -> (Supplier<? extends SimpleBuildItem>) () -> bc.consume(buildItemClass));
                } else if (isSupplierOfOptionalOf(parameterType, SimpleBuildItem.class)) {
                    final Class<? extends SimpleBuildItem> buildItemClass = rawTypeOfParameter(rawTypeOfParameter(parameterType, 0), 0).asSubclass(SimpleBuildItem.class);
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(buildItemClass, ConsumeFlags.of(ConsumeFlag.OPTIONAL)));
                    methodParamFns.add((bc, bri) -> (Supplier<Optional<? extends SimpleBuildItem>>) () -> Optional.ofNullable(bc.consume(buildItemClass)));
                } else if (rawTypeOf(parameterType) == Executor.class) {
                    methodParamFns.add((bc, bri) -> bc.getExecutor());
                } else if (parameterClass.isAnnotationPresent(ConfigRoot.class)) {
                    final ConfigRoot annotation = parameterClass.getAnnotation(ConfigRoot.class);
                    final ConfigPhase phase = annotation.phase();
                    methodConsumingConfigPhases.add(phase);
                    if (phase.isAvailableAtBuild()) {
                        methodParamFns.add((bc, bri) -> {
                            final ConfigurationBuildItem configurationBuildItem = bc.consume(ConfigurationBuildItem.class);
                            return configurationBuildItem.getReadResult().requireObjectForClass(parameterClass);
                        });
                        if (isRecorder && phase == ConfigPhase.BUILD_AND_RUN_TIME_FIXED) {
                            runTimeProxies.computeIfAbsent(parameterClass, readResult::requireObjectForClass);
                        }
                    } else if (phase.isReadAtMain()) {
                        if (isRecorder) {
                            methodParamFns.add((bc, bri) -> {
                                final RunTimeConfigurationProxyBuildItem proxies = bc.consume(RunTimeConfigurationProxyBuildItem.class);
                                return proxies.getProxyObjectFor(parameterClass);
                            });
                            runTimeProxies.computeIfAbsent(parameterClass, ConfigMappingUtils::newInstance);
                        } else {
                            throw reportError(parameter, phase + " configuration cannot be consumed here unless the method is a @Recorder");
                        }
                    } else {
                        throw reportError(parameterClass, "Unknown value for ConfigPhase");
                    }
                } else if (isRecorder(parameter.getType())) {
                    if (!isRecorder) {
                        throw reportError(parameter, "Cannot pass recorders to method which is not annotated with " + Record.class);
                    }
                    methodParamFns.add((bc, bri) -> {
                        assert bri != null;
                        return bri.getRecordingProxy(parameterClass);
                    });
                    // now look for recorder parameter injection
                    // as we now inject config directly into recorders we need to look at the constructor params
                    Constructor<?>[] ctors = parameter.getType().getDeclaredConstructors();
                    for (var ctor : ctors) {
                        if (ctors.length == 1 || ctor.isAnnotationPresent(Inject.class)) {
                            for (var type : ctor.getGenericParameterTypes()) {
                                Class<?> theType = null;
                                if (type instanceof ParameterizedType) {
                                    ParameterizedType pt = (ParameterizedType) type;
                                    if (pt.getRawType().equals(RuntimeValue.class)) {
                                        theType = (Class<?>) pt.getActualTypeArguments()[0];
                                    } else {
                                        throw new RuntimeException("Unknown recorder constructor parameter: " + type + " in recorder " + parameter.getType());
                                    }
                                } else {
                                    theType = (Class<?>) type;
                                }
                                ConfigRoot annotation = theType.getAnnotation(ConfigRoot.class);
                                if (annotation != null) {
                                    if (recordAnnotation.value() == ExecutionTime.STATIC_INIT) {
                                        methodConsumingConfigPhases.add(ConfigPhase.BUILD_AND_RUN_TIME_FIXED);
                                    } else {
                                        methodConsumingConfigPhases.add(annotation.phase());
                                    }
                                    if (annotation.phase().isReadAtMain()) {
                                        runTimeProxies.computeIfAbsent(theType, ConfigMappingUtils::newInstance);
                                    } else {
                                        runTimeProxies.computeIfAbsent(theType, readResult::requireObjectForClass);
                                    }
                                }
                            }
                        }
                    }
                } else if (parameter.getType() == RecorderContext.class || parameter.getType() == BytecodeRecorderImpl.class) {
                    if (!isRecorder) {
                        throw reportError(parameter, "Cannot pass recorder context to method which is not annotated with " + Record.class);
                    }
                    methodParamFns.add((bc, bri) -> bri);
                } else {
                    throw reportError(parameter, "Unsupported method parameter " + parameterType);
                }
            }
        }
        final BiConsumer<BuildContext, Object> resultConsumer;
        final Type returnType = method.getGenericReturnType();
        final boolean weak = method.isAnnotationPresent(Weak.class);
        final boolean overridable = method.isAnnotationPresent(Overridable.class);
        if (rawTypeIs(returnType, void.class)) {
            resultConsumer = Functions.discardingBiConsumer();
        } else if (rawTypeExtends(returnType, BuildItem.class)) {
            final Class<? extends BuildItem> type = method.getReturnType().asSubclass(BuildItem.class);
            if (overridable) {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE));
                }
            } else {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type));
                }
            }
            resultConsumer = (bc, o) -> {
                if (o != null)
                    bc.produce((BuildItem) o);
            };
        } else if (isOptionalOf(returnType, BuildItem.class)) {
            final Class<? extends BuildItem> type = rawTypeOfParameter(returnType, 0).asSubclass(BuildItem.class);
            if (overridable) {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE));
                }
            } else {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type));
                }
            }
            resultConsumer = (bc, o) -> ((Optional<? extends BuildItem>) o).ifPresent(bc::produce);
        } else if (isListOf(returnType, MultiBuildItem.class)) {
            final Class<? extends MultiBuildItem> type = rawTypeOfParameter(returnType, 0).asSubclass(MultiBuildItem.class);
            if (overridable) {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.OVERRIDABLE));
                }
            } else {
                if (weak) {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type, ProduceFlag.WEAK));
                } else {
                    methodStepConfig = methodStepConfig.andThen(bsb -> bsb.produces(type));
                }
            }
            resultConsumer = (bc, o) -> {
                if (o != null)
                    bc.produce((List<? extends MultiBuildItem>) o);
            };
        } else {
            throw reportError(method, "Unsupported method return type " + returnType);
        }
        if (methodConsumingConfigPhases.contains(ConfigPhase.BOOTSTRAP) || methodConsumingConfigPhases.contains(ConfigPhase.RUN_TIME)) {
            if (isRecorder && recordAnnotation.value() == ExecutionTime.STATIC_INIT) {
                throw reportError(method, "Bytecode recorder is static but an injected config object is declared as run time");
            }
            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(RunTimeConfigurationProxyBuildItem.class));
            if (methodConsumingConfigPhases.contains(ConfigPhase.BOOTSTRAP)) {
                methodStepConfig = methodStepConfig.andThen(bsb -> bsb.afterProduce(BootstrapConfigSetupCompleteBuildItem.class));
            }
            if (methodConsumingConfigPhases.contains(ConfigPhase.RUN_TIME)) {
                methodStepConfig = methodStepConfig.andThen(bsb -> bsb.afterProduce(RuntimeConfigSetupCompleteBuildItem.class));
            }
        }
        if (methodConsumingConfigPhases.contains(ConfigPhase.BUILD_AND_RUN_TIME_FIXED) || methodConsumingConfigPhases.contains(ConfigPhase.BUILD_TIME)) {
            methodStepConfig = methodStepConfig.andThen(bsb -> bsb.consumes(ConfigurationBuildItem.class));
        }
        final Consume[] consumes = method.getAnnotationsByType(Consume.class);
        if (consumes.length > 0) {
            methodStepConfig = methodStepConfig.andThen(bsb -> {
                for (Consume consume : consumes) {
                    bsb.afterProduce(consume.value());
                }
            });
        }
        final Produce[] produces = method.getAnnotationsByType(Produce.class);
        if (produces.length > 0) {
            methodStepConfig = methodStepConfig.andThen(bsb -> {
                for (Produce produce : produces) {
                    bsb.beforeConsume(produce.value());
                }
            });
        }
        final ProduceWeak[] produceWeaks = method.getAnnotationsByType(ProduceWeak.class);
        if (produceWeaks.length > 0) {
            methodStepConfig = methodStepConfig.andThen(bsb -> {
                for (ProduceWeak produceWeak : produceWeaks) {
                    bsb.beforeConsume(produceWeak.value(), ProduceFlag.WEAK);
                }
            });
        }
        final Consumer<BuildStepBuilder> finalStepConfig = stepConfig.andThen(methodStepConfig).andThen(buildStepBuilder -> buildStepBuilder.buildIf(finalAddStep));
        final BiConsumer<BuildContext, Object> finalStepInstanceSetup = stepInstanceSetup;
        final String name = clazz.getName() + "#" + method.getName();
        chainConfig = chainConfig.andThen(bcb -> {
            BuildStepBuilder bsb = bcb.addBuildStep(new io.quarkus.builder.BuildStep() {

                public void execute(final BuildContext bc) {
                    Object[] ctorArgs = new Object[ctorParamFns.size()];
                    for (int i = 0; i < ctorArgs.length; i++) {
                        ctorArgs[i] = ctorParamFns.get(i).apply(bc);
                    }
                    Object instance;
                    try {
                        instance = constructor.newInstance(ctorArgs);
                    } catch (InstantiationException e) {
                        throw ReflectUtil.toError(e);
                    } catch (IllegalAccessException e) {
                        throw ReflectUtil.toError(e);
                    } catch (InvocationTargetException e) {
                        try {
                            throw e.getCause();
                        } catch (RuntimeException | Error e2) {
                            throw e2;
                        } catch (Throwable t) {
                            throw new IllegalStateException(t);
                        }
                    }
                    finalStepInstanceSetup.accept(bc, instance);
                    Object[] methodArgs = new Object[methodParamFns.size()];
                    BytecodeRecorderImpl bri = isRecorder ? new BytecodeRecorderImpl(recordAnnotation.value() == ExecutionTime.STATIC_INIT, clazz.getSimpleName(), method.getName(), Integer.toString(Math.abs(method.toString().hashCode())), identityComparison, s -> {
                        if (s instanceof Class) {
                            var cfg = ((Class<?>) s).getAnnotation(ConfigRoot.class);
                            if (cfg == null || (cfg.phase() != ConfigPhase.BUILD_AND_RUN_TIME_FIXED && recordAnnotation.value() == ExecutionTime.STATIC_INIT)) {
                                throw new RuntimeException("Can only inject BUILD_AND_RUN_TIME_FIXED objects into a constructor, use RuntimeValue to inject runtime config: " + s);
                            }
                            return runTimeProxies.get(s);
                        }
                        if (s instanceof ParameterizedType) {
                            ParameterizedType p = (ParameterizedType) s;
                            if (p.getRawType() == RuntimeValue.class) {
                                Object object = runTimeProxies.get(p.getActualTypeArguments()[0]);
                                if (object == null) {
                                    return new RuntimeValue<>();
                                }
                                return new RuntimeValue<>(object);
                            }
                        }
                        return null;
                    }) : null;
                    for (int i = 0; i < methodArgs.length; i++) {
                        methodArgs[i] = methodParamFns.get(i).apply(bc, bri);
                    }
                    Object result;
                    try {
                        result = method.invoke(instance, methodArgs);
                    } catch (IllegalAccessException e) {
                        throw ReflectUtil.toError(e);
                    } catch (InvocationTargetException e) {
                        try {
                            throw e.getCause();
                        } catch (RuntimeException | Error e2) {
                            throw e2;
                        } catch (Throwable t) {
                            throw new IllegalStateException(t);
                        }
                    }
                    resultConsumer.accept(bc, result);
                    if (isRecorder) {
                        // commit recorded data
                        if (recordAnnotation.value() == ExecutionTime.STATIC_INIT) {
                            bc.produce(new StaticBytecodeRecorderBuildItem(bri));
                        } else {
                            bc.produce(new MainBytecodeRecorderBuildItem(bri));
                        }
                    }
                }

                public String toString() {
                    return name;
                }
            });
            finalStepConfig.accept(bsb);
        });
    }
    return chainConfig;
}
Also used : RootDefinition(io.quarkus.deployment.configuration.definition.RootDefinition) ReflectUtil.isSupplierOfOptionalOf(io.quarkus.deployment.util.ReflectUtil.isSupplierOfOptionalOf) RecorderContext(io.quarkus.deployment.recording.RecorderContext) BooleanSupplier(java.util.function.BooleanSupplier) Functions(org.wildfly.common.function.Functions) ReflectUtil.isSupplierOf(io.quarkus.deployment.util.ReflectUtil.isSupplierOf) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) BytecodeCreator(io.quarkus.gizmo.BytecodeCreator) Recorder(io.quarkus.runtime.annotations.Recorder) ConsumeFlags(io.quarkus.builder.ConsumeFlags) RunTimeConfigurationProxyBuildItem(io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem) ReflectUtil.rawTypeIs(io.quarkus.deployment.util.ReflectUtil.rawTypeIs) KeyMap(io.smallrye.config.KeyMap) EnumSet(java.util.EnumSet) Consume(io.quarkus.deployment.annotations.Consume) Member(java.lang.reflect.Member) MainBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.MainBytecodeRecorderBuildItem) StaticBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.StaticBytecodeRecorderBuildItem) ReflectUtil.isBuildProducerOf(io.quarkus.deployment.util.ReflectUtil.isBuildProducerOf) InvocationTargetException(java.lang.reflect.InvocationTargetException) Weak(io.quarkus.deployment.annotations.Weak) ApplicationModel(io.quarkus.bootstrap.model.ApplicationModel) ConfigProvider(org.eclipse.microprofile.config.ConfigProvider) ConsumeFlag(io.quarkus.builder.ConsumeFlag) PropertiesConfigSource(io.smallrye.config.PropertiesConfigSource) ConfigClassWithPrefix(io.smallrye.config.ConfigMappings.ConfigClassWithPrefix) ResultHandle(io.quarkus.gizmo.ResultHandle) AnnotatedElement(java.lang.reflect.AnnotatedElement) Record(io.quarkus.deployment.annotations.Record) ProduceWeak(io.quarkus.deployment.annotations.ProduceWeak) DevModeType(io.quarkus.dev.spi.DevModeType) ReflectUtil.rawTypeOf(io.quarkus.deployment.util.ReflectUtil.rawTypeOf) BuildStepBuilder(io.quarkus.builder.BuildStepBuilder) BuildItem(io.quarkus.builder.item.BuildItem) SimpleBuildItem(io.quarkus.builder.item.SimpleBuildItem) Constructor(java.lang.reflect.Constructor) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) ConfigRoot(io.quarkus.runtime.annotations.ConfigRoot) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) Parameter(java.lang.reflect.Parameter) BiConsumer(java.util.function.BiConsumer) KeyMapBackedConfigSource(io.smallrye.config.KeyMapBackedConfigSource) Properties(java.util.Properties) Executor(java.util.concurrent.Executor) IOException(java.io.IOException) Field(java.lang.reflect.Field) FieldDescriptor(io.quarkus.gizmo.FieldDescriptor) ParameterizedType(java.lang.reflect.ParameterizedType) SmallRyeConfigBuilder(io.smallrye.config.SmallRyeConfigBuilder) ConfigPhase(io.quarkus.runtime.annotations.ConfigPhase) BiFunction(java.util.function.BiFunction) ProduceFlags(io.quarkus.builder.ProduceFlags) Overridable(io.quarkus.deployment.annotations.Overridable) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) ConfigProviderResolver(org.eclipse.microprofile.config.spi.ConfigProviderResolver) ProduceFlag(io.quarkus.builder.ProduceFlag) ReflectUtil(io.quarkus.deployment.util.ReflectUtil) Method(java.lang.reflect.Method) BootstrapConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem) IdentityHashMap(java.util.IdentityHashMap) ReflectUtil.isOptionalOf(io.quarkus.deployment.util.ReflectUtil.isOptionalOf) ReflectUtil.rawTypeExtends(io.quarkus.deployment.util.ReflectUtil.rawTypeExtends) ExecutionTime(io.quarkus.deployment.annotations.ExecutionTime) Config(org.eclipse.microprofile.config.Config) DefaultValuesConfigurationSource(io.quarkus.deployment.configuration.DefaultValuesConfigurationSource) List(java.util.List) BuildContext(io.quarkus.builder.BuildContext) Type(java.lang.reflect.Type) Modifier(java.lang.reflect.Modifier) Optional(java.util.Optional) ConfigMappingUtils(io.quarkus.deployment.configuration.ConfigMappingUtils) ConfigUtils(io.quarkus.runtime.configuration.ConfigUtils) Logger(org.jboss.logging.Logger) LaunchMode(io.quarkus.runtime.LaunchMode) HashMap(java.util.HashMap) Function(java.util.function.Function) ReflectUtil.isConsumerOf(io.quarkus.deployment.util.ReflectUtil.isConsumerOf) Inject(javax.inject.Inject) ConfigurationBuildItem(io.quarkus.deployment.builditem.ConfigurationBuildItem) BuildStep(io.quarkus.deployment.annotations.BuildStep) ReflectUtil.isListOf(io.quarkus.deployment.util.ReflectUtil.isListOf) RuntimeValue(io.quarkus.runtime.RuntimeValue) RuntimeConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem) ObjectLoader(io.quarkus.deployment.recording.ObjectLoader) QuarkusConfigFactory(io.quarkus.runtime.configuration.QuarkusConfigFactory) BytecodeRecorderObjectLoaderBuildItem(io.quarkus.deployment.builditem.BytecodeRecorderObjectLoaderBuildItem) MethodDescriptor(io.quarkus.gizmo.MethodDescriptor) SmallRyeConfig(io.smallrye.config.SmallRyeConfig) BuildTimeConfigurationReader(io.quarkus.deployment.configuration.BuildTimeConfigurationReader) Produce(io.quarkus.deployment.annotations.Produce) Consumer(java.util.function.Consumer) MultiBuildItem(io.quarkus.builder.item.MultiBuildItem) NameIterator(io.smallrye.config.NameIterator) ReflectUtil.rawTypeOfParameter(io.quarkus.deployment.util.ReflectUtil.rawTypeOfParameter) ServiceUtil(io.quarkus.deployment.util.ServiceUtil) BytecodeRecorderImpl(io.quarkus.deployment.recording.BytecodeRecorderImpl) Collections(java.util.Collections) BuildProducer(io.quarkus.deployment.annotations.BuildProducer) ConfigRoot(io.quarkus.runtime.annotations.ConfigRoot) Produce(io.quarkus.deployment.annotations.Produce) SimpleBuildItem(io.quarkus.builder.item.SimpleBuildItem) ConfigPhase(io.quarkus.runtime.annotations.ConfigPhase) Optional(java.util.Optional) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) Consume(io.quarkus.deployment.annotations.Consume) BuildContext(io.quarkus.builder.BuildContext) BuildChainBuilder(io.quarkus.builder.BuildChainBuilder) RuntimeValue(io.quarkus.runtime.RuntimeValue) MultiBuildItem(io.quarkus.builder.item.MultiBuildItem) RecorderContext(io.quarkus.deployment.recording.RecorderContext) BuildStep(io.quarkus.deployment.annotations.BuildStep) StaticBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.StaticBytecodeRecorderBuildItem) ParameterizedType(java.lang.reflect.ParameterizedType) BiFunction(java.util.function.BiFunction) Function(java.util.function.Function) Field(java.lang.reflect.Field) Executor(java.util.concurrent.Executor) BooleanSupplier(java.util.function.BooleanSupplier) Supplier(java.util.function.Supplier) Record(io.quarkus.deployment.annotations.Record) ConfigurationBuildItem(io.quarkus.deployment.builditem.ConfigurationBuildItem) BooleanSupplier(java.util.function.BooleanSupplier) BytecodeRecorderImpl(io.quarkus.deployment.recording.BytecodeRecorderImpl) Constructor(java.lang.reflect.Constructor) RunTimeConfigurationProxyBuildItem(io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem) MainBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.MainBytecodeRecorderBuildItem) StaticBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.StaticBytecodeRecorderBuildItem) BuildItem(io.quarkus.builder.item.BuildItem) SimpleBuildItem(io.quarkus.builder.item.SimpleBuildItem) BootstrapConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.BootstrapConfigSetupCompleteBuildItem) ConfigurationBuildItem(io.quarkus.deployment.builditem.ConfigurationBuildItem) RuntimeConfigSetupCompleteBuildItem(io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem) BytecodeRecorderObjectLoaderBuildItem(io.quarkus.deployment.builditem.BytecodeRecorderObjectLoaderBuildItem) MultiBuildItem(io.quarkus.builder.item.MultiBuildItem) ExecutionTime(io.quarkus.deployment.annotations.ExecutionTime) DevModeType(io.quarkus.dev.spi.DevModeType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) BuildStepBuilder(io.quarkus.builder.BuildStepBuilder) BiFunction(java.util.function.BiFunction) RunTimeConfigurationProxyBuildItem(io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem) ProduceWeak(io.quarkus.deployment.annotations.ProduceWeak) Parameter(java.lang.reflect.Parameter) ReflectUtil.rawTypeOfParameter(io.quarkus.deployment.util.ReflectUtil.rawTypeOfParameter) MainBytecodeRecorderBuildItem(io.quarkus.deployment.builditem.MainBytecodeRecorderBuildItem)

Aggregations

ApplicationModel (io.quarkus.bootstrap.model.ApplicationModel)2 BuildChainBuilder (io.quarkus.builder.BuildChainBuilder)2 BuildContext (io.quarkus.builder.BuildContext)2 BuildStepBuilder (io.quarkus.builder.BuildStepBuilder)2 ConsumeFlag (io.quarkus.builder.ConsumeFlag)2 ConsumeFlags (io.quarkus.builder.ConsumeFlags)2 ProduceFlag (io.quarkus.builder.ProduceFlag)2 ProduceFlags (io.quarkus.builder.ProduceFlags)2 BuildItem (io.quarkus.builder.item.BuildItem)2 MultiBuildItem (io.quarkus.builder.item.MultiBuildItem)2 SimpleBuildItem (io.quarkus.builder.item.SimpleBuildItem)2 BuildProducer (io.quarkus.deployment.annotations.BuildProducer)2 BuildStep (io.quarkus.deployment.annotations.BuildStep)2 Consume (io.quarkus.deployment.annotations.Consume)2 ExecutionTime (io.quarkus.deployment.annotations.ExecutionTime)2 Overridable (io.quarkus.deployment.annotations.Overridable)2 Produce (io.quarkus.deployment.annotations.Produce)2 ProduceWeak (io.quarkus.deployment.annotations.ProduceWeak)2 Record (io.quarkus.deployment.annotations.Record)2 Weak (io.quarkus.deployment.annotations.Weak)2