Search in sources :

Example 1 with ServiceDefinition

use of com.palantir.dialogue.annotations.processor.data.ServiceDefinition in project dialogue by palantir.

the class DialogueRequestAnnotationsProcessor method generateDialogueServiceFactory.

private JavaFile generateDialogueServiceFactory(Element annotatedInterface, Collection<Element> annotatedMethods) {
    ElementKind kind = annotatedInterface.getKind();
    Preconditions.checkArgument(kind.isInterface(), "Only methods on interfaces can be annotated with @Request");
    Set<Element> nonMethodElements = annotatedMethods.stream().filter(element -> !element.getKind().equals(ElementKind.METHOD)).collect(Collectors.toSet());
    validationStep(ctx -> nonMethodElements.forEach(nonMethodElement -> ctx.reportError("Only methods can be annotated with @Request", nonMethodElement)));
    Preconditions.checkArgument(nonMethodElements.isEmpty(), "Only methods can be annotated with @Request");
    List<EndpointDefinition> endpoints = processingStep(ctx -> {
        EndpointDefinitions endpointDefinitions = new EndpointDefinitions(ctx, elements, types);
        List<Optional<EndpointDefinition>> maybeEndpoints = annotatedMethods.stream().map(MoreElements::asExecutable).map(endpointDefinitions::tryParseEndpointDefinition).collect(Collectors.toList());
        Preconditions.checkArgument(maybeEndpoints.stream().filter(Predicates.not(Optional::isPresent)).collect(Collectors.toList()).isEmpty(), "Failed validation");
        return maybeEndpoints.stream().map(Optional::get).collect(Collectors.toList());
    });
    ClassName serviceInterface = ClassName.get(MoreElements.getPackage(annotatedInterface).getQualifiedName().toString(), annotatedInterface.getSimpleName().toString());
    ServiceDefinition serviceDefinition = ImmutableServiceDefinition.builder().serviceInterface(serviceInterface).addAllEndpoints(endpoints).build();
    TypeSpec generatedClass = new DialogueServiceFactoryGenerator(serviceDefinition).generate();
    TypeSpec withOriginatingElement = generatedClass.toBuilder().addOriginatingElement(annotatedInterface).build();
    MoreElements.getAnnotationMirror(annotatedInterface, DialogueService.class).toJavaUtil().map(mirror -> AnnotationMirrors.getAnnotationValue(mirror, "value")).ifPresent(value -> value.accept(new SimpleAnnotationValueVisitor9<Void, Void>() {

        @Override
        public Void visitType(TypeMirror type, Void _unused) {
            // Quick check, the generated type is expected, however a hand-written
            // type may be used instead. This avoids a class of problems involving
            // dependencies between processor rounds.
            String typeName = type.toString();
            String expectedGenerated = serviceInterface.packageName() + '.' + generatedClass.name;
            if (typeName.equals(expectedGenerated)) {
                return null;
            }
            TypeElement factoryElement = elements.getTypeElement(DialogueServiceFactory.class.getName());
            if (factoryElement == null) {
                return null;
            }
            DeclaredType expectedType = types.getDeclaredType(factoryElement, types.getWildcardType(annotatedInterface.asType(), null));
            if (!types.isAssignable(type, expectedType)) {
                messager.printMessage(Kind.ERROR, "@DialogueService annotation references an " + "invalid DialogueServiceFactory type", annotatedInterface);
            }
            return null;
        }
    }, null));
    return JavaFile.builder(serviceInterface.packageName(), withOriginatingElement).build();
}
Also used : ElementKind(javax.lang.model.element.ElementKind) AbstractProcessor(javax.annotation.processing.AbstractProcessor) CompileTimeConstant(com.google.errorprone.annotations.CompileTimeConstant) ClassName(com.squareup.javapoet.ClassName) TypeElement(javax.lang.model.element.TypeElement) Function(java.util.function.Function) Elements(javax.lang.model.util.Elements) EndpointDefinitions(com.palantir.dialogue.annotations.processor.data.EndpointDefinitions) Kind(javax.tools.Diagnostic.Kind) ImmutableServiceDefinition(com.palantir.dialogue.annotations.processor.data.ImmutableServiceDefinition) DeclaredType(javax.lang.model.type.DeclaredType) Predicates(com.google.common.base.Predicates) DialogueService(com.palantir.dialogue.DialogueService) Arg(com.palantir.logsafe.Arg) Messager(javax.annotation.processing.Messager) Goethe(com.palantir.goethe.Goethe) MoreElements(com.google.auto.common.MoreElements) ImmutableSet(com.google.common.collect.ImmutableSet) ElementKind(javax.lang.model.element.ElementKind) Request(com.palantir.dialogue.annotations.Request) SafeRuntimeException(com.palantir.logsafe.exceptions.SafeRuntimeException) KeyedStream(com.palantir.common.streams.KeyedStream) GoetheException(com.palantir.goethe.GoetheException) SimpleAnnotationValueVisitor9(javax.lang.model.util.SimpleAnnotationValueVisitor9) Collection(java.util.Collection) ServiceDefinition(com.palantir.dialogue.annotations.processor.data.ServiceDefinition) Throwables(com.google.common.base.Throwables) Set(java.util.Set) Element(javax.lang.model.element.Element) TypeSpec(com.squareup.javapoet.TypeSpec) Types(javax.lang.model.util.Types) DialogueServiceFactory(com.palantir.dialogue.DialogueServiceFactory) Collectors(java.util.stream.Collectors) JavaFile(com.squareup.javapoet.JavaFile) Consumer(java.util.function.Consumer) SourceVersion(javax.lang.model.SourceVersion) SafeExceptions(com.palantir.logsafe.exceptions.SafeExceptions) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) FilerException(javax.annotation.processing.FilerException) RoundEnvironment(javax.annotation.processing.RoundEnvironment) Filer(javax.annotation.processing.Filer) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Optional(java.util.Optional) DialogueServiceFactoryGenerator(com.palantir.dialogue.annotations.processor.generate.DialogueServiceFactoryGenerator) AnnotationMirrors(com.google.auto.common.AnnotationMirrors) Preconditions(com.palantir.logsafe.Preconditions) EndpointDefinition(com.palantir.dialogue.annotations.processor.data.EndpointDefinition) Optional(java.util.Optional) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) EndpointDefinition(com.palantir.dialogue.annotations.processor.data.EndpointDefinition) SimpleAnnotationValueVisitor9(javax.lang.model.util.SimpleAnnotationValueVisitor9) MoreElements(com.google.auto.common.MoreElements) DialogueServiceFactoryGenerator(com.palantir.dialogue.annotations.processor.generate.DialogueServiceFactoryGenerator) TypeMirror(javax.lang.model.type.TypeMirror) DialogueServiceFactory(com.palantir.dialogue.DialogueServiceFactory) ClassName(com.squareup.javapoet.ClassName) DialogueService(com.palantir.dialogue.DialogueService) ImmutableServiceDefinition(com.palantir.dialogue.annotations.processor.data.ImmutableServiceDefinition) ServiceDefinition(com.palantir.dialogue.annotations.processor.data.ServiceDefinition) EndpointDefinitions(com.palantir.dialogue.annotations.processor.data.EndpointDefinitions) TypeSpec(com.squareup.javapoet.TypeSpec) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

AnnotationMirrors (com.google.auto.common.AnnotationMirrors)1 MoreElements (com.google.auto.common.MoreElements)1 Predicates (com.google.common.base.Predicates)1 Throwables (com.google.common.base.Throwables)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 CompileTimeConstant (com.google.errorprone.annotations.CompileTimeConstant)1 KeyedStream (com.palantir.common.streams.KeyedStream)1 DialogueService (com.palantir.dialogue.DialogueService)1 DialogueServiceFactory (com.palantir.dialogue.DialogueServiceFactory)1 Request (com.palantir.dialogue.annotations.Request)1 EndpointDefinition (com.palantir.dialogue.annotations.processor.data.EndpointDefinition)1 EndpointDefinitions (com.palantir.dialogue.annotations.processor.data.EndpointDefinitions)1 ImmutableServiceDefinition (com.palantir.dialogue.annotations.processor.data.ImmutableServiceDefinition)1 ServiceDefinition (com.palantir.dialogue.annotations.processor.data.ServiceDefinition)1 DialogueServiceFactoryGenerator (com.palantir.dialogue.annotations.processor.generate.DialogueServiceFactoryGenerator)1 Goethe (com.palantir.goethe.Goethe)1 GoetheException (com.palantir.goethe.GoetheException)1 Arg (com.palantir.logsafe.Arg)1 Preconditions (com.palantir.logsafe.Preconditions)1 SafeExceptions (com.palantir.logsafe.exceptions.SafeExceptions)1