• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
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  *   https://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 package com.google.android.enterprise.connectedapps.processor.containers;
17 
18 import com.google.android.enterprise.connectedapps.annotations.CustomFutureWrapper;
19 import com.google.auto.value.AutoValue;
20 import com.squareup.javapoet.ClassName;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import javax.lang.model.element.TypeElement;
24 import javax.lang.model.type.TypeMirror;
25 
26 /** Information about future wrapper. */
27 @AutoValue
28 public abstract class FutureWrapper {
29 
30   /** The type of the Wrapper. This controls how supporting code is generated. */
31   public enum WrapperType {
32     DEFAULT, // Copied from a resource
33     CUSTOM // Included in classpath
34   }
35 
36   public static final String FUTURE_WRAPPER_PACKAGE =
37       "com.google.android.enterprise.connectedapps.futurewrappers";
38 
wrappedType()39   public abstract TypeMirror wrappedType();
40 
defaultWrapperClassName()41   public abstract ClassName defaultWrapperClassName();
42 
wrapperClassName()43   public abstract ClassName wrapperClassName();
44 
wrapperType()45   public abstract WrapperType wrapperType();
46 
create( TypeMirror wrappedType, ClassName defaultWrapperClassName, WrapperType wrapperType)47   private static FutureWrapper create(
48       TypeMirror wrappedType, ClassName defaultWrapperClassName, WrapperType wrapperType) {
49     return create(wrappedType, defaultWrapperClassName, defaultWrapperClassName, wrapperType);
50   }
51 
create( TypeMirror wrappedType, ClassName defaultWrapperClassName, ClassName wrapperClassName, WrapperType wrapperType)52   public static FutureWrapper create(
53       TypeMirror wrappedType,
54       ClassName defaultWrapperClassName,
55       ClassName wrapperClassName,
56       WrapperType wrapperType) {
57     return new AutoValue_FutureWrapper(
58         wrappedType, defaultWrapperClassName, wrapperClassName, wrapperType);
59   }
60 
createGlobalFutureWrappers(Context context)61   public static Collection<FutureWrapper> createGlobalFutureWrappers(Context context) {
62     Collection<FutureWrapper> wrappers = new ArrayList<>();
63 
64     addDefaultFutureWrappers(context, wrappers);
65 
66     return wrappers;
67   }
68 
addDefaultFutureWrappers( Context context, Collection<FutureWrapper> wrappers)69   private static void addDefaultFutureWrappers(
70       Context context, Collection<FutureWrapper> wrappers) {
71     tryAddWrapper(
72         context,
73         wrappers,
74         "com.google.common.util.concurrent.ListenableFuture",
75         ClassName.get(FUTURE_WRAPPER_PACKAGE, "ListenableFutureWrapper"),
76         WrapperType.DEFAULT);
77   }
78 
createCustomFutureWrappers( Context context, Collection<TypeElement> customFutureWrappers)79   public static Collection<FutureWrapper> createCustomFutureWrappers(
80       Context context, Collection<TypeElement> customFutureWrappers) {
81     Collection<FutureWrapper> wrappers = new ArrayList<>();
82 
83     addCustomFutureWrappers(context, wrappers, customFutureWrappers);
84 
85     return wrappers;
86   }
87 
addCustomFutureWrappers( Context context, Collection<FutureWrapper> wrappers, Collection<TypeElement> customFutureWrappers)88   private static void addCustomFutureWrappers(
89       Context context,
90       Collection<FutureWrapper> wrappers,
91       Collection<TypeElement> customFutureWrappers) {
92     for (TypeElement customFutureWrapper : customFutureWrappers) {
93       addCustomFutureWrapper(context, wrappers, customFutureWrapper);
94     }
95   }
96 
addCustomFutureWrapper( Context context, Collection<FutureWrapper> wrappers, TypeElement customFutureWrapper)97   private static void addCustomFutureWrapper(
98       Context context, Collection<FutureWrapper> wrappers, TypeElement customFutureWrapper) {
99     CustomFutureWrapper customFutureWrapperAnnotation =
100         customFutureWrapper.getAnnotation(CustomFutureWrapper.class);
101 
102     if (customFutureWrapperAnnotation == null) {
103       // This will be dealt with as part of early validation
104       return;
105     }
106 
107     tryAddWrapper(
108         context,
109         wrappers,
110         FutureWrapperAnnotationInfo.extractFromFutureWrapperAnnotation(
111                 context, customFutureWrapperAnnotation)
112             .originalType()
113             .toString(),
114         ClassName.get(customFutureWrapper),
115         WrapperType.CUSTOM);
116   }
117 
tryAddWrapper( Context context, Collection<FutureWrapper> wrappers, String typeQualifiedName, ClassName wrapperClassName, WrapperType wrapperType)118   private static void tryAddWrapper(
119       Context context,
120       Collection<FutureWrapper> wrappers,
121       String typeQualifiedName,
122       ClassName wrapperClassName,
123       WrapperType wrapperType) {
124     TypeElement typeElement = context.elements().getTypeElement(typeQualifiedName);
125 
126     if (typeElement == null) {
127       // The type isn't supported at compile-time - so won't be included in this app
128       return;
129     }
130 
131     wrappers.add(FutureWrapper.create(typeElement.asType(), wrapperClassName, wrapperType));
132   }
133 }
134