• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static dagger.internal.codegen.SourceFiles.setFactoryClassName;
21 
22 import com.squareup.javapoet.CodeBlock;
23 import dagger.model.DependencyRequest;
24 import dagger.producers.Produced;
25 import java.util.Optional;
26 
27 /** A factory creation expression for a multibound set. */
28 final class SetFactoryCreationExpression extends MultibindingFactoryCreationExpression {
29 
30   private final ComponentImplementation componentImplementation;
31   private final BindingGraph graph;
32   private final ContributionBinding binding;
33 
SetFactoryCreationExpression( ContributionBinding binding, ComponentImplementation componentImplementation, ComponentBindingExpressions componentBindingExpressions, BindingGraph graph)34   SetFactoryCreationExpression(
35       ContributionBinding binding,
36       ComponentImplementation componentImplementation,
37       ComponentBindingExpressions componentBindingExpressions,
38       BindingGraph graph) {
39     super(binding, componentImplementation, componentBindingExpressions);
40     this.binding = checkNotNull(binding);
41     this.componentImplementation = checkNotNull(componentImplementation);
42     this.graph = checkNotNull(graph);
43   }
44 
45   @Override
creationExpression()46   public CodeBlock creationExpression() {
47     CodeBlock.Builder builder = CodeBlock.builder().add("$T.", setFactoryClassName(binding));
48     if (!useRawType()) {
49       SetType setType = SetType.from(binding.key());
50       builder.add(
51           "<$T>",
52           setType.elementsAreTypeOf(Produced.class)
53               ? setType.unwrappedElementType(Produced.class)
54               : setType.elementType());
55     }
56 
57     int individualProviders = 0;
58     int setProviders = 0;
59     CodeBlock.Builder builderMethodCalls = CodeBlock.builder();
60     String methodNameSuffix =
61         binding.bindingType().equals(BindingType.PROVISION) ? "Provider" : "Producer";
62 
63     Optional<CodeBlock> superContributions = superContributions();
64     if (superContributions.isPresent()) {
65       // TODO(b/117833324): consider decomposing the Provider<Set<Provider>> and adding the
66       // individual contributions separately from the collection contributions. Though this may
67       // actually not be doable/desirable if the super provider instance is a DelegateFactory or
68       // another internal type that is not SetFactory
69       builderMethodCalls.add(".addCollection$N($L)", methodNameSuffix, superContributions.get());
70       setProviders++;
71     }
72 
73     for (DependencyRequest dependency : dependenciesToImplement()) {
74       ContributionType contributionType =
75           graph.contributionBindings().get(dependency.key()).contributionType();
76       String methodNamePrefix;
77       switch (contributionType) {
78         case SET:
79           individualProviders++;
80           methodNamePrefix = "add";
81           break;
82         case SET_VALUES:
83           setProviders++;
84           methodNamePrefix = "addCollection";
85           break;
86         default:
87           throw new AssertionError(dependency + " is not a set multibinding");
88       }
89 
90       builderMethodCalls.add(
91           ".$N$N($L)",
92           methodNamePrefix,
93           methodNameSuffix,
94           multibindingDependencyExpression(dependency));
95     }
96     builder.add("builder($L, $L)", individualProviders, setProviders);
97     builder.add(builderMethodCalls.build());
98 
99     componentImplementation.registerImplementedMultibinding(binding, bindingRequest());
100 
101     return builder.add(".build()").build();
102   }
103 }
104