in sample/experiments-compiler/experiment-enums-compiler/java/src/main/java/com/uber/crumb/sample/experimentenumscompiler/ExperimentsCompiler.java [88:175]
public void consume(
CrumbContext context,
TypeElement type,
Collection<? extends AnnotationMirror> annotations,
Set<? extends Map<String, String>> metadata) {
// Must be an abstract class because we're generating the backing implementation.
if (type.getKind() != ElementKind.CLASS) {
context
.getProcessingEnv()
.getMessager()
.printMessage(
Diagnostic.Kind.ERROR,
"@"
+ ExperimentsCollector.class.getSimpleName()
+ " is only applicable on classes when consuming!",
type);
return;
} else if (!type.getModifiers().contains(ABSTRACT)) {
context
.getProcessingEnv()
.getMessager()
.printMessage(Diagnostic.Kind.ERROR, "Must be abstract!", type);
}
// Map of enum TypeElement to its members
Map<TypeElement, Set<String>> experimentClasses =
metadata
.stream()
.map(data -> data.get(METADATA_KEY))
.map(
enumClass -> context.getProcessingEnv().getElementUtils().getTypeElement(enumClass))
.collect(
toMap(
typeElement -> typeElement,
typeElement ->
typeElement
.getEnclosedElements()
.stream()
.filter(e -> e.getKind() == ElementKind.ENUM_CONSTANT)
.map(Object::toString)
.collect(toSet())));
FieldSpec mapField =
FieldSpec.builder(
ParameterizedTypeName.get(
ClassName.get(Map.class),
TypeName.get(Class.class),
ParameterizedTypeName.get(List.class, String.class)),
"EXPERIMENTS",
PUBLIC,
STATIC,
FINAL)
.initializer(CodeBlock.of("new $T<>()", LinkedHashMap.class))
.build();
CodeBlock.Builder staticInitBlock = CodeBlock.builder();
experimentClasses.forEach(
(key, value) ->
staticInitBlock.addStatement(
"$N.put($T.class, $T.asList($L))",
mapField,
TypeName.get(key.asType()),
TypeName.get(Arrays.class),
String.join(", ", value.stream().map(s -> "\"" + s + "\"").collect(toList()))));
TypeSpec generatedClass =
TypeSpec.classBuilder("Experiments_" + type.getSimpleName().toString())
.addModifiers(PUBLIC, FINAL)
.superclass(TypeName.get(type.asType()))
.addField(mapField)
.addStaticBlock(staticInitBlock.build())
.build();
try {
JavaFile.builder(MoreElements.getPackage(type).getQualifiedName().toString(), generatedClass)
.build()
.writeTo(context.getProcessingEnv().getFiler());
} catch (IOException e) {
context
.getProcessingEnv()
.getMessager()
.printMessage(
Diagnostic.Kind.ERROR,
"Failed to write generated experiments mapping! " + e.getMessage(),
type);
}
}