use of com.palantir.dialogue.annotations.processor.data.EndpointDefinition in project dialogue by palantir.
the class ServiceImplementationGenerator method clientImpl.
private MethodSpec clientImpl(EndpointDefinition def) {
List<ParameterSpec> params = def.arguments().stream().map(arg -> ParameterSpec.builder(ArgumentTypes.caseOf(arg.argType()).primitive((javaTypeName, _parameterSerializerMethodName, _isList) -> javaTypeName).rawRequestBody(typeName -> typeName).optional((optionalJavaType, _unused) -> optionalJavaType).mapType(typeName -> typeName).customType(typeName -> typeName), arg.argName().get()).build()).collect(Collectors.toList());
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(def.endpointName().get()).addModifiers(Modifier.PUBLIC).addParameters(params).addAnnotation(Override.class);
methodBuilder.addCode("$T $L = $T.builder();", Request.Builder.class, REQUEST, Request.class);
def.arguments().forEach(arg -> methodBuilder.addCode(generateParam(arg)));
methodBuilder.returns(def.returns().returnType());
boolean isAsync = def.returns().asyncInnerType().isPresent();
String executeCode = isAsync ? "$L.clients().call($L, $L.build(), $L);" : "$L.clients().callBlocking($L, $L.build(), $L);";
CodeBlock execute = CodeBlock.of(executeCode, serviceDefinition.conjureRuntimeArgName(), def.channelFieldName(), REQUEST, def.returns().deserializerFieldName());
methodBuilder.addCode(!def.returns().isVoid() || isAsync ? "return $L" : "$L", execute);
return methodBuilder.build();
}
use of com.palantir.dialogue.annotations.processor.data.EndpointDefinition 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();
}
Aggregations