• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 dagger.internal.codegen.RequestKinds.requestType;
20 
21 import com.google.auto.value.AutoValue;
22 import dagger.internal.codegen.langmodel.DaggerTypes;
23 import dagger.internal.codegen.serialization.BindingRequestProto;
24 import dagger.internal.codegen.serialization.FrameworkTypeWrapper;
25 import dagger.internal.codegen.serialization.RequestKindWrapper;
26 import dagger.model.DependencyRequest;
27 import dagger.model.Key;
28 import dagger.model.RequestKind;
29 import java.util.Optional;
30 import javax.lang.model.type.TypeMirror;
31 
32 /**
33  * A request for a binding, which may be in the form of a request for a dependency to pass to a
34  * constructor or module method ({@link RequestKind}) or an internal request for a framework
35  * instance ({@link FrameworkType}).
36  */
37 @AutoValue
38 abstract class BindingRequest {
39   /** Creates a {@link BindingRequest} for the given {@link DependencyRequest}. */
bindingRequest(DependencyRequest dependencyRequest)40   static BindingRequest bindingRequest(DependencyRequest dependencyRequest) {
41     return bindingRequest(dependencyRequest.key(), dependencyRequest.kind());
42   }
43 
44   /**
45    * Creates a {@link BindingRequest} for a normal dependency request for the given {@link Key} and
46    * {@link RequestKind}.
47    */
bindingRequest(Key key, RequestKind requestKind)48   static BindingRequest bindingRequest(Key key, RequestKind requestKind) {
49     // When there's a request that has a 1:1 mapping to a FrameworkType, the request should be
50     // associated with that FrameworkType as well, because we want to ensure that if a request
51     // comes in for that as a dependency first and as a framework instance later, they resolve to
52     // the same binding expression.
53     // TODO(cgdecker): Instead of doing this, make ComponentBindingExpressions create a
54     // BindingExpression for the RequestKind that simply delegates to the BindingExpression for the
55     // FrameworkType. Then there are separate BindingExpressions, but we don't end up doing weird
56     // things like creating two fields when there should only be one.
57     return new AutoValue_BindingRequest(
58         key, Optional.of(requestKind), FrameworkType.forRequestKind(requestKind));
59   }
60 
61   /**
62    * Creates a {@link BindingRequest} for a request for a framework instance for the given {@link
63    * Key} with the given {@link FrameworkType}.
64    */
bindingRequest(Key key, FrameworkType frameworkType)65   static BindingRequest bindingRequest(Key key, FrameworkType frameworkType) {
66     return new AutoValue_BindingRequest(
67         key, frameworkType.requestKind(), Optional.of(frameworkType));
68   }
69 
70   /** Creates a {@link BindingRequest} for the given {@link FrameworkDependency}. */
bindingRequest(FrameworkDependency frameworkDependency)71   static BindingRequest bindingRequest(FrameworkDependency frameworkDependency) {
72     return bindingRequest(frameworkDependency.key(), frameworkDependency.frameworkType());
73   }
74 
75   /** Returns the {@link Key} for the requested binding. */
key()76   abstract Key key();
77 
78   /** Returns the request kind associated with this request, if any. */
requestKind()79   abstract Optional<RequestKind> requestKind();
80 
81   /** Returns the framework type associated with this request, if any. */
frameworkType()82   abstract Optional<FrameworkType> frameworkType();
83 
84   /** Returns whether this request is of the given kind. */
isRequestKind(RequestKind requestKind)85   final boolean isRequestKind(RequestKind requestKind) {
86     return requestKind.equals(requestKind().orElse(null));
87   }
88 
requestedType(TypeMirror contributedType, DaggerTypes types)89   final TypeMirror requestedType(TypeMirror contributedType, DaggerTypes types) {
90     if (requestKind().isPresent()) {
91       return requestType(requestKind().get(), contributedType, types);
92     }
93     return types.wrapType(contributedType, frameworkType().get().frameworkClass());
94   }
95 
96   /** Returns a name that can be used for the kind of request this is. */
kindName()97   final String kindName() {
98     Object requestKindObject =
99         requestKind().isPresent()
100             ? requestKind().get()
101             : frameworkType().get().frameworkClass().getSimpleName();
102     return requestKindObject.toString();
103   }
104 
105   /** Returns {@code true} if this request can be satisfied by a production binding. */
canBeSatisfiedByProductionBinding()106   final boolean canBeSatisfiedByProductionBinding() {
107     if (requestKind().isPresent()) {
108       return RequestKinds.canBeSatisfiedByProductionBinding(requestKind().get());
109     }
110     return frameworkType().get().equals(FrameworkType.PRODUCER_NODE);
111   }
112 
113   /** Creates a proto representation of this binding request. */
toProto()114   BindingRequestProto toProto() {
115     BindingRequestProto.Builder builder =
116         BindingRequestProto.newBuilder().setKey(KeyFactory.toProto(key()));
117     if (frameworkType().isPresent()) {
118       builder.setFrameworkType(
119           FrameworkTypeWrapper.FrameworkType.valueOf(frameworkType().get().name()));
120     } else {
121       builder.setRequestKind(RequestKindWrapper.RequestKind.valueOf(requestKind().get().name()));
122     }
123     return builder.build();
124   }
125 }
126