package com.airbnb.epoxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
class DataBindingProcessor {
private final Elements elementUtils;
private final Types typeUtils;
private final ErrorLogger errorLogger;
private final ConfigManager configManager;
private final LayoutResourceProcessor layoutResourceProcessor;
private final DataBindingModuleLookup dataBindingModuleLookup;
private final GeneratedModelWriter modelWriter;
private final List<DataBindingModelInfo> modelInfoList = new ArrayList<>();
DataBindingProcessor(Elements elementUtils, Types typeUtils, ErrorLogger errorLogger,
ConfigManager configManager, LayoutResourceProcessor layoutResourceProcessor,
DataBindingModuleLookup dataBindingModuleLookup, GeneratedModelWriter modelWriter) {
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
this.errorLogger = errorLogger;
this.configManager = configManager;
this.layoutResourceProcessor = layoutResourceProcessor;
this.dataBindingModuleLookup = dataBindingModuleLookup;
this.modelWriter = modelWriter;
}
void process(RoundEnvironment roundEnv) {
Set<? extends Element> dataBindingLayoutPackageElements =
roundEnv.getElementsAnnotatedWith(EpoxyDataBindingLayouts.class);
for (Element packageElement : dataBindingLayoutPackageElements) {
List<LayoutResource> layoutResources = layoutResourceProcessor
.getLayoutsInAnnotation(packageElement, EpoxyDataBindingLayouts.class);
// Get the module name after parsing resources so we can use the resource classes to figure
// out the module name
String moduleName = dataBindingModuleLookup.getModuleName(packageElement);
for (LayoutResource layoutResource : layoutResources) {
modelInfoList.add(new DataBindingModelInfo(typeUtils, elementUtils, layoutResource,
moduleName));
}
}
}
List<DataBindingModelInfo> resolveDataBindingClassesAndWriteJava() {
for (DataBindingModelInfo modelInfo : modelInfoList) {
// This should be called in the last round of processing so the data binding classes will
// have been generated by now and we can parse them to get the databinding variables
modelInfo.parseDataBindingClass();
}
writeJava();
return modelInfoList;
}
private void writeJava() {
for (DataBindingModelInfo modelInfo : modelInfoList) {
try {
modelWriter.generateClassForModel(modelInfo);
} catch (Exception e) {
errorLogger.logError(e, "Error generating model classes");
}
}
}
}