use of com.palantir.conjure.spec.ArgumentName in project conjure-java by palantir.
the class Retrofit2ServiceGenerator method extractEncodedPathArgs.
private Set<ArgumentName> extractEncodedPathArgs(HttpPath path) {
Pattern pathArg = Pattern.compile("\\{([^\\}]+)\\}");
Matcher matcher = pathArg.matcher(path.toString());
ImmutableSet.Builder<ArgumentName> encodedArgs = ImmutableSet.builder();
while (matcher.find()) {
String arg = matcher.group(1);
if (arg.contains(":")) {
// Strip everything after first colon
encodedArgs.add(ArgumentName.of(arg.substring(0, arg.indexOf(':'))));
}
}
return encodedArgs.build();
}
use of com.palantir.conjure.spec.ArgumentName in project conjure-java by palantir.
the class Retrofit2ServiceGenerator method generateCompatibilityBackfillServiceMethods.
/**
* Provides a linear expansion of optional query arguments to improve Java back-compat.
*/
private List<MethodSpec> generateCompatibilityBackfillServiceMethods(EndpointDefinition endpointDef, TypeMapper returnTypeMapper, TypeMapper argumentTypeMapper) {
Set<ArgumentName> encodedPathArgs = extractEncodedPathArgs(endpointDef.getHttpPath());
List<ArgumentDefinition> queryArgs = new ArrayList<>();
for (ArgumentDefinition arg : endpointDef.getArgs()) {
if (arg.getParamType().accept(ParameterTypeVisitor.IS_QUERY) && arg.getType().accept(DefaultableTypeVisitor.INSTANCE)) {
queryArgs.add(arg);
}
}
List<MethodSpec> alternateMethods = new ArrayList<>();
for (int i = 0; i < queryArgs.size(); i++) {
alternateMethods.add(createCompatibilityBackfillMethod(endpointDef, returnTypeMapper, argumentTypeMapper, encodedPathArgs, queryArgs.subList(i, queryArgs.size())));
}
return alternateMethods;
}
use of com.palantir.conjure.spec.ArgumentName in project conjure-java by palantir.
the class Retrofit2ServiceGenerator method generateServiceMethod.
private MethodSpec generateServiceMethod(EndpointDefinition endpointDef, TypeMapper returnTypeMapper, TypeMapper argumentTypeMapper) {
TypeName returnType = endpointDef.getReturns().map(returnTypeMapper::getClassName).orElse(ClassName.VOID);
Set<ArgumentName> encodedPathArgs = extractEncodedPathArgs(endpointDef.getHttpPath());
HttpPath endpointPathWithoutRegex = replaceEncodedPathArgs(endpointDef.getHttpPath());
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(endpointDef.getEndpointName().get()).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).addAnnotation(AnnotationSpec.builder(httpMethodToClassName(endpointDef.getHttpMethod().get().name())).addMember("value", "$S", "." + endpointPathWithoutRegex).build()).addAnnotation(AnnotationSpec.builder(ClassName.get("retrofit2.http", "Headers")).addMember("value", "$S", "hr-path-template: " + endpointPathWithoutRegex).addMember("value", "$S", "Accept: " + getReturnMediaType(returnType)).build());
if (returnType.equals(BINARY_RETURN_TYPE) || returnType.equals(OPTIONAL_BINARY_RETURN_TYPE)) {
methodBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("retrofit2.http", "Streaming")).build());
}
endpointDef.getDeprecated().ifPresent(deprecatedDocsValue -> methodBuilder.addAnnotation(ClassName.get("java.lang", "Deprecated")));
methodBuilder.addAnnotations(ConjureAnnotations.getClientEndpointAnnotations(endpointDef));
ServiceGenerators.getJavaDoc(endpointDef).ifPresent(content -> methodBuilder.addJavadoc("$L", content));
methodBuilder.returns(ParameterizedTypeName.get(LISTENABLE_FUTURE_TYPE, returnType.box()));
methodBuilder.addParameters(createServiceMethodParameters(endpointDef, argumentTypeMapper, encodedPathArgs));
return methodBuilder.build();
}
use of com.palantir.conjure.spec.ArgumentName in project conjure by palantir.
the class ConjureParserUtils method parseArgs.
private static List<ArgumentDefinition> parseArgs(Map<ParameterName, com.palantir.conjure.parser.services.ArgumentDefinition> args, HttpPath httpPath, ReferenceTypeResolver typeResolver) {
ImmutableList.Builder<ArgumentDefinition> resultBuilder = ImmutableList.builder();
for (Map.Entry<ParameterName, com.palantir.conjure.parser.services.ArgumentDefinition> entry : args.entrySet()) {
com.palantir.conjure.parser.services.ArgumentDefinition original = entry.getValue();
ArgumentName argName = ArgumentName.of(entry.getKey().name());
ParameterType paramType = parseParameterType(original, argName, httpPath);
ArgumentDefinition.Builder builder = ArgumentDefinition.builder().argName(argName).type(original.type().visit(new ConjureTypeParserVisitor(typeResolver))).paramType(paramType).docs(original.docs().map(Documentation::of)).safety(original.safety().map(ConjureParserUtils::parseLogSafety)).markers(parseMarkers(original.markers(), typeResolver)).tags(original.tags().stream().peek(tag -> Preconditions.checkArgument(!tag.isEmpty(), "tag must not be empty")).collect(Collectors.toSet()));
resultBuilder.add(builder.build());
}
return resultBuilder.build();
}
use of com.palantir.conjure.spec.ArgumentName in project conjure-java by palantir.
the class Retrofit2ServiceGenerator method createCompatibilityBackfillMethod.
private MethodSpec createCompatibilityBackfillMethod(EndpointDefinition endpointDef, TypeMapper returnTypeMapper, TypeMapper argumentTypeMapper, Set<ArgumentName> encodedPathArgs, List<ArgumentDefinition> extraArgs) {
TypeName returnType = endpointDef.getReturns().map(returnTypeMapper::getClassName).orElse(ClassName.VOID);
// ensure the correct ordering of parameters by creating the complete sorted parameter list
List<ParameterSpec> sortedParams = createServiceMethodParameters(endpointDef, argumentTypeMapper, encodedPathArgs);
List<Optional<ArgumentDefinition>> sortedMaybeExtraArgs = sortedParams.stream().map(param -> extraArgs.stream().filter(arg -> arg.getArgName().get().equals(param.name)).findFirst()).collect(Collectors.toList());
// omit extraArgs from the back fill method signature
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(endpointDef.getEndpointName().get()).addModifiers(Modifier.PUBLIC, Modifier.DEFAULT).addAnnotation(Deprecated.class).addParameters(IntStream.range(0, sortedParams.size()).filter(i -> !sortedMaybeExtraArgs.get(i).isPresent()).mapToObj(sortedParams::get).collect(Collectors.toList())).addAnnotations(ConjureAnnotations.getClientEndpointAnnotations(endpointDef));
endpointDef.getReturns().ifPresent(type -> methodBuilder.returns(ParameterizedTypeName.get(LISTENABLE_FUTURE_TYPE, returnType.box())));
// replace extraArgs with default values when invoking the complete method
StringBuilder sb = new StringBuilder(endpointDef.getReturns().isPresent() ? "return $N(" : "$N(");
List<Object> values = IntStream.range(0, sortedParams.size()).mapToObj(i -> {
Optional<ArgumentDefinition> maybeArgDef = sortedMaybeExtraArgs.get(i);
if (maybeArgDef.isPresent()) {
sb.append("$L, ");
return maybeArgDef.get().getType().accept(DefaultTypeValueVisitor.INSTANCE);
} else {
sb.append("$N, ");
return sortedParams.get(i);
}
}).collect(Collectors.toList());
// trim the end
sb.setLength(sb.length() - 2);
sb.append(")");
ImmutableList<Object> methodCallArgs = ImmutableList.builder().add(endpointDef.getEndpointName().get()).addAll(values).build();
methodBuilder.addStatement(sb.toString(), methodCallArgs.toArray(new Object[0]));
return methodBuilder.build();
}
Aggregations