ProcessDataBinding.java revision b1356339eaa6c8e967e4fc1dc283b82909a1208d
1/* 2 * Copyright (C) 2015 The Android Open Source Project 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 17package android.databinding.annotationprocessor; 18 19import android.databinding.BindingBuildInfo; 20import android.databinding.tool.reflection.ModelAnalyzer; 21import android.databinding.tool.writer.AnnotationJavaFileWriter; 22import android.databinding.tool.writer.JavaFileWriter; 23 24import java.util.Arrays; 25import java.util.List; 26import java.util.Set; 27 28import javax.annotation.processing.AbstractProcessor; 29import javax.annotation.processing.ProcessingEnvironment; 30import javax.annotation.processing.RoundEnvironment; 31import javax.annotation.processing.SupportedAnnotationTypes; 32import javax.annotation.processing.SupportedSourceVersion; 33import javax.lang.model.SourceVersion; 34import javax.lang.model.element.TypeElement; 35 36@SupportedAnnotationTypes({ 37 "android.databinding.BindingAdapter", 38 "android.databinding.Untaggable", 39 "android.databinding.BindingMethods", 40 "android.databinding.BindingConversion", 41 "android.databinding.BindingBuildInfo"} 42) 43@SupportedSourceVersion(SourceVersion.RELEASE_7) 44/** 45 * Parent annotation processor that dispatches sub steps to ensure execution order. 46 * Use initProcessingSteps to add a new step. 47 */ 48public class ProcessDataBinding extends AbstractProcessor { 49 private List<ProcessingStep> mProcessingSteps; 50 @Override 51 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 52 if (mProcessingSteps == null) { 53 initProcessingSteps(); 54 } 55 final BindingBuildInfo buildInfo = BuildInfoUtil.load(roundEnv); 56 if (buildInfo == null) { 57 return false; 58 } 59 boolean done = true; 60 for (ProcessingStep step : mProcessingSteps) { 61 done = step.runStep(roundEnv, processingEnv, buildInfo) && done; 62 } 63 if (roundEnv.processingOver()) { 64 for (ProcessingStep step : mProcessingSteps) { 65 step.onProcessingOver(roundEnv, processingEnv, buildInfo); 66 } 67 } 68 return done; 69 } 70 71 private void initProcessingSteps() { 72 ProcessBindable processBindable = new ProcessBindable(); 73 mProcessingSteps = Arrays.asList( 74 new ProcessMethodAdapters(), 75 new ProcessExpressions(processBindable), 76 processBindable 77 ); 78 AnnotationJavaFileWriter javaFileWriter = new AnnotationJavaFileWriter(processingEnv); 79 for (ProcessingStep step : mProcessingSteps) { 80 step.mJavaFileWriter = javaFileWriter; 81 } 82 } 83 84 @Override 85 public synchronized void init(ProcessingEnvironment processingEnv) { 86 super.init(processingEnv); 87 ModelAnalyzer.setProcessingEnvironment(processingEnv); 88 } 89 90 /** 91 * To ensure execution order and binding build information, we use processing steps. 92 */ 93 public abstract static class ProcessingStep { 94 private boolean mDone; 95 private JavaFileWriter mJavaFileWriter; 96 97 protected JavaFileWriter getWriter() { 98 return mJavaFileWriter; 99 } 100 101 private boolean runStep(RoundEnvironment roundEnvironment, 102 ProcessingEnvironment processingEnvironment, 103 BindingBuildInfo buildInfo) { 104 if (mDone) { 105 return true; 106 } 107 mDone = onHandleStep(roundEnvironment, processingEnvironment, buildInfo); 108 return mDone; 109 } 110 111 /** 112 * Invoked in each annotation processing step. 113 * 114 * @return True if it is done and should never be invoked again. 115 */ 116 abstract public boolean onHandleStep(RoundEnvironment roundEnvironment, 117 ProcessingEnvironment processingEnvironment, 118 BindingBuildInfo buildInfo); 119 120 /** 121 * Invoked when processing is done. A good place to generate the output if the 122 * processor requires multiple steps. 123 */ 124 abstract public void onProcessingOver(RoundEnvironment roundEnvironment, 125 ProcessingEnvironment processingEnvironment, 126 BindingBuildInfo buildInfo); 127 } 128} 129