| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.room.processing |
| |
| import androidx.room.processing.javac.JavacElement |
| import androidx.room.processing.javac.JavacProcessingEnv |
| import com.google.auto.common.BasicAnnotationProcessor |
| import com.google.auto.common.MoreElements |
| import com.google.common.collect.SetMultimap |
| import javax.lang.model.element.Element |
| import javax.tools.Diagnostic |
| import kotlin.reflect.KClass |
| |
| /** |
| * Specialized processing step which only supports annotations on TypeElements. |
| * |
| * We can generalize it but for now, Room only needs annotations on TypeElements to start |
| * processing. |
| */ |
| interface XProcessingStep { |
| /** |
| * The implementation of processing logic for the step. It is guaranteed that the keys in |
| * [elementsByAnnotation] will be a subset of the set returned by [annotations]. |
| * |
| * @return the elements (a subset of the values of [elementsByAnnotation]) that this step |
| * is unable to process, possibly until a later processing round. These elements will be |
| * passed back to this step at the next round of processing. |
| */ |
| fun process( |
| env: XProcessingEnv, |
| elementsByAnnotation: Map<KClass<out Annotation>, List<XTypeElement>> |
| ): Set<XTypeElement> |
| |
| /** |
| * The set of annotations processed by this step. |
| */ |
| fun annotations(): Set<KClass<out Annotation>> |
| |
| /** |
| * Wraps current [XProcessingStep] into an Auto Common |
| * [BasicAnnotationProcessor.ProcessingStep]. |
| */ |
| fun asAutoCommonProcessor( |
| env: XProcessingEnv |
| ): BasicAnnotationProcessor.ProcessingStep { |
| return JavacProcessingStepDelegate( |
| env = env as JavacProcessingEnv, |
| delegate = this |
| ) |
| } |
| } |
| |
| @Suppress("UnstableApiUsage") |
| internal class JavacProcessingStepDelegate( |
| val env: JavacProcessingEnv, |
| val delegate: XProcessingStep |
| ) : BasicAnnotationProcessor.ProcessingStep { |
| override fun process( |
| elementsByAnnotation: SetMultimap<Class<out Annotation>, Element> |
| ): Set<Element> { |
| val converted = mutableMapOf<KClass<out Annotation>, List<XTypeElement>>() |
| annotations().forEach { annotation -> |
| val elements = elementsByAnnotation[annotation].mapNotNull { element -> |
| if (MoreElements.isType(element)) { |
| env.wrapTypeElement(MoreElements.asType(element)) |
| } else { |
| env.delegate.messager.printMessage( |
| Diagnostic.Kind.ERROR, |
| "Unsupported element type: ${element.kind}", |
| element |
| ) |
| null |
| } |
| } |
| converted[annotation.kotlin] = elements |
| } |
| val result = delegate.process(env, converted) |
| return result.map { |
| (it as JavacElement).element |
| }.toSet() |
| } |
| |
| override fun annotations(): Set<Class<out Annotation>> { |
| return delegate.annotations().mapTo(mutableSetOf()) { |
| it.java |
| } |
| } |
| } |