private String generateClass(TypeElement type, String className, String ifaceToImpl, boolean isFinal) {
        if (type == null) {
            mErrorReporter.abortWithError("generateClass was invoked with null type", null);
            return null;
        }
        if (className == null) {
            mErrorReporter.abortWithError("generateClass was invoked with null class name", type);
            return null;
        }
        if (ifaceToImpl == null) {
            mErrorReporter.abortWithError("generateClass was invoked with null iface", type);
            return null;
        }

        String pkg = CompilerUtil.packageNameOf(type);

        ClassName strClz = ClassName.get("java.lang", "Runnable");
        ClassName intClz = ClassName.get("java.lang", "Integer");
        ClassName mapClz = ClassName.get("java.util", "Map");
        TypeName mapOfString = ParameterizedTypeName.get(mapClz, intClz, strClz);
        FieldSpec onGrantMethodsMap = FieldSpec.builder(mapOfString, "ON_GRANT_METHODS_MAP")
                .addModifiers(Modifier.STATIC, Modifier.FINAL, Modifier.PRIVATE).build();

        FieldSpec onDenyMethodsMap = FieldSpec.builder(mapOfString, "ON_DENY_METHODS_MAP")
                .addModifiers(Modifier.STATIC, Modifier.FINAL, Modifier.PRIVATE).build();

        TypeSpec.Builder subClass = TypeSpec.classBuilder(className)
                .addField(boolean.class, "DEBUG", Modifier.STATIC, Modifier.FINAL, Modifier.PRIVATE)
                .addStaticBlock(CodeBlock.of("DEBUG = " + DEBUG + ";\n"))
                .addField(onGrantMethodsMap)
                .addField(onDenyMethodsMap)
                .addStaticBlock(CodeBlock.of("ON_GRANT_METHODS_MAP = new $T<>();\n", HashMap.class))
                .addStaticBlock(CodeBlock.of("ON_DENY_METHODS_MAP = new $T<>();\n", HashMap.class))
                .addMethods(createMethodSpecs(type));

        // Add type params.
        List l = type.getTypeParameters();
        Collections.consumeRemaining(l, o -> {
            TypeParameterElement typeParameterElement = (TypeParameterElement) o;
            subClass.addTypeVariable(TypeVariableName.get(typeParameterElement.toString()));
        });

        if (isFinal) subClass.addModifiers(FINAL);

        JavaFile javaFile = JavaFile.builder(pkg, subClass.build())
                .addFileComment(SettingsProvider.FILE_COMMENT)
                .skipJavaLangImports(true)
                .build();
        return javaFile.toString();
    }
Created by guohao4 on 2017/9/6.
Email: Tornaco@163.com
android/annotation_processors/permission-requester-compiler/src/main/java/github/tornaco/permission/compiler/RuntimePermissionsCompiler.java