1 /* 2 * Copyright (C) 2016 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.grpc.server.processor; 18 19 import static javax.lang.model.util.ElementFilter.typesIn; 20 21 import com.google.auto.common.BasicAnnotationProcessor; 22 import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep; 23 import com.google.auto.service.AutoService; 24 import com.google.common.collect.ImmutableList; 25 import com.google.common.collect.ImmutableSet; 26 import com.google.common.collect.SetMultimap; 27 import com.google.googlejavaformat.java.filer.FormattingFiler; 28 import com.squareup.javapoet.ClassName; 29 import com.squareup.javapoet.JavaFile; 30 import dagger.grpc.server.GrpcService; 31 import java.io.IOException; 32 import java.lang.annotation.Annotation; 33 import java.util.Set; 34 import javax.annotation.processing.Processor; 35 import javax.lang.model.SourceVersion; 36 import javax.lang.model.element.Element; 37 import javax.lang.model.element.TypeElement; 38 import javax.tools.Diagnostic.Kind; 39 40 /** 41 * Generates code from types annotated with {@link GrpcService @GrpcService}. 42 * 43 * @see <a href="https://dagger.dev/dev-guide/grpc">https://dagger.dev/dev-guide/grpc</a> 44 */ 45 @AutoService(Processor.class) 46 public class GrpcServiceProcessor extends BasicAnnotationProcessor implements ProcessingStep { 47 48 @Override initSteps()49 protected ImmutableList<GrpcServiceProcessor> initSteps() { 50 return ImmutableList.of(this); 51 } 52 53 @Override annotations()54 public ImmutableSet<Class<GrpcService>> annotations() { 55 return ImmutableSet.of(GrpcService.class); 56 } 57 58 @Override getSupportedSourceVersion()59 public SourceVersion getSupportedSourceVersion() { 60 return SourceVersion.latest(); 61 } 62 63 @Override process( SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation)64 public Set<Element> process( 65 SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) { 66 ImmutableSet.Builder<Element> deferredElements = ImmutableSet.builder(); 67 for (TypeElement element : typesIn(elementsByAnnotation.get(GrpcService.class))) { 68 try { 69 GrpcServiceModel grpcServiceModel = new GrpcServiceModel(processingEnv, element); 70 if (grpcServiceModel.validate()) { 71 write(new ServiceDefinitionTypeGenerator(grpcServiceModel), element); 72 write(new ProxyModuleGenerator(grpcServiceModel), element); 73 write(new GrpcServiceModuleGenerator(grpcServiceModel), element); 74 write(new UnscopedGrpcServiceModuleGenerator(grpcServiceModel), element); 75 } 76 } catch (TypeNotPresentException e) { 77 deferredElements.add(element); 78 } 79 } 80 return deferredElements.build(); 81 } 82 write(SourceGenerator grpcServiceTypeWriter, final TypeElement element)83 private void write(SourceGenerator grpcServiceTypeWriter, final TypeElement element) { 84 JavaFile javaFile = grpcServiceTypeWriter.javaFile(); 85 ClassName outputClassName = ClassName.get(javaFile.packageName, javaFile.typeSpec.name); 86 try { 87 javaFile.writeTo(new FormattingFiler(processingEnv.getFiler())); 88 } catch (IOException e) { 89 processingEnv 90 .getMessager() 91 .printMessage( 92 Kind.ERROR, String.format("Error writing %s: %s", outputClassName, e), element); 93 } 94 } 95 } 96