1 /* 2 * Copyright (C) 2021 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen.writing; 18 19 import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; 20 import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; 21 import static dagger.internal.codegen.model.BindingKind.DELEGATE; 22 import static dagger.internal.codegen.writing.ProvisionBindingRepresentation.needsCaching; 23 24 import dagger.assisted.Assisted; 25 import dagger.assisted.AssistedFactory; 26 import dagger.assisted.AssistedInject; 27 import dagger.internal.codegen.binding.BindingGraph; 28 import dagger.internal.codegen.binding.BindingRequest; 29 import dagger.internal.codegen.binding.FrameworkType; 30 import dagger.internal.codegen.binding.ProvisionBinding; 31 import dagger.internal.codegen.model.RequestKind; 32 import java.util.HashMap; 33 import java.util.Map; 34 35 /** Returns request representation that wraps a framework instance expression */ 36 final class FrameworkInstanceBindingRepresentation { 37 private final ProvisionBinding binding; 38 private final DerivedFromFrameworkInstanceRequestRepresentation.Factory 39 derivedFromFrameworkInstanceRequestRepresentationFactory; 40 private final ImmediateFutureRequestRepresentation.Factory 41 immediateFutureRequestRepresentationFactory; 42 private final Map<BindingRequest, RequestRepresentation> requestRepresentations = new HashMap<>(); 43 private final RequestRepresentation providerRequestRepresentation; 44 private final RequestRepresentation producerFromProviderRepresentation; 45 46 @AssistedInject FrameworkInstanceBindingRepresentation( @ssisted ProvisionBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, DelegateRequestRepresentation.Factory delegateRequestRepresentationFactory, DerivedFromFrameworkInstanceRequestRepresentation.Factory derivedFromFrameworkInstanceRequestRepresentationFactory, ImmediateFutureRequestRepresentation.Factory immediateFutureRequestRepresentationFactory, ProducerNodeInstanceRequestRepresentation.Factory producerNodeInstanceRequestRepresentationFactory, ProviderInstanceRequestRepresentation.Factory providerInstanceRequestRepresentationFactory, ProducerFromProviderCreationExpression.Factory producerFromProviderCreationExpressionFactory)47 FrameworkInstanceBindingRepresentation( 48 @Assisted ProvisionBinding binding, 49 BindingGraph graph, 50 ComponentImplementation componentImplementation, 51 DelegateRequestRepresentation.Factory delegateRequestRepresentationFactory, 52 DerivedFromFrameworkInstanceRequestRepresentation.Factory 53 derivedFromFrameworkInstanceRequestRepresentationFactory, 54 ImmediateFutureRequestRepresentation.Factory immediateFutureRequestRepresentationFactory, 55 ProducerNodeInstanceRequestRepresentation.Factory 56 producerNodeInstanceRequestRepresentationFactory, 57 ProviderInstanceRequestRepresentation.Factory providerInstanceRequestRepresentationFactory, 58 ProducerFromProviderCreationExpression.Factory 59 producerFromProviderCreationExpressionFactory) { 60 this.binding = binding; 61 this.derivedFromFrameworkInstanceRequestRepresentationFactory = 62 derivedFromFrameworkInstanceRequestRepresentationFactory; 63 this.immediateFutureRequestRepresentationFactory = immediateFutureRequestRepresentationFactory; 64 this.providerRequestRepresentation = 65 binding.kind().equals(DELEGATE) && !needsCaching(binding, graph) 66 ? delegateRequestRepresentationFactory.create(binding, RequestKind.PROVIDER) 67 : providerInstanceRequestRepresentationFactory.create(binding); 68 this.producerFromProviderRepresentation = 69 producerNodeInstanceRequestRepresentationFactory.create( 70 binding, 71 new FrameworkFieldInitializer( 72 componentImplementation, 73 binding, 74 producerFromProviderCreationExpressionFactory.create( 75 providerRequestRepresentation, 76 componentImplementation.shardImplementation(binding).name()))); 77 } 78 getRequestRepresentation(BindingRequest request)79 public RequestRepresentation getRequestRepresentation(BindingRequest request) { 80 return reentrantComputeIfAbsent( 81 requestRepresentations, request, this::getRequestRepresentationUncached); 82 } 83 getRequestRepresentationUncached(BindingRequest request)84 private RequestRepresentation getRequestRepresentationUncached(BindingRequest request) { 85 switch (request.requestKind()) { 86 case INSTANCE: 87 case LAZY: 88 case PRODUCED: 89 case PROVIDER_OF_LAZY: 90 return derivedFromFrameworkInstanceRequestRepresentationFactory.create( 91 binding, providerRequestRepresentation, request.requestKind(), FrameworkType.PROVIDER); 92 case PROVIDER: 93 return providerRequestRepresentation; 94 case PRODUCER: 95 return producerFromProviderRepresentation; 96 97 case FUTURE: 98 return immediateFutureRequestRepresentationFactory.create( 99 getRequestRepresentation(bindingRequest(binding.key(), RequestKind.INSTANCE)), 100 binding.key().type().xprocessing()); 101 102 default: 103 throw new AssertionError( 104 String.format("Invalid binding request kind: %s", request.requestKind())); 105 } 106 } 107 108 @AssistedFactory 109 static interface Factory { create(ProvisionBinding binding)110 FrameworkInstanceBindingRepresentation create(ProvisionBinding binding); 111 } 112 } 113