private ImmutableMap<TypeMirror, FieldSpec> getTypeAdapters(List<JsonProperty> properties, NameAllocator nameAllocator) { Map<TypeMirror, FieldSpec> typeAdapters = new LinkedHashMap<>(); for (JsonProperty property : properties) { if (property.typeAdapter != null && !typeAdapters.containsKey(property.typeAdapter)) { ClassName typeName = (ClassName) TypeName.get(property.typeAdapter); String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, typeName.simpleName()); name = nameAllocator.newName(name, typeName); typeAdapters.put(property.typeAdapter, FieldSpec.builder(typeName, NameAllocator.toJavaIdentifier(name), PRIVATE, STATIC, FINAL).initializer("new $T()", typeName).build()); } } return ImmutableMap.copyOf(typeAdapters); }
private ImmutableMap<TypeMirror, FieldSpec> getTypeAdapters(ImmutableList<Property> properties) { Map<TypeMirror, FieldSpec> typeAdapters = new LinkedHashMap<>(); NameAllocator nameAllocator = new NameAllocator(); nameAllocator.newName("CREATOR"); for (Property property : properties) { if (property.typeAdapter != null && !typeAdapters.containsKey(property.typeAdapter)) { ClassName typeName = (ClassName) TypeName.get(property.typeAdapter); String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, typeName.simpleName()); name = nameAllocator.newName(name, typeName); typeAdapters.put(property.typeAdapter, FieldSpec.builder( typeName, NameAllocator.toJavaIdentifier(name), PRIVATE, STATIC, FINAL) .initializer("new $T()", typeName).build()); } } return ImmutableMap.copyOf(typeAdapters); }
ImmutableMap<TypeName, FieldSpec> createFields(List<Property> properties) { ImmutableMap.Builder<TypeName, FieldSpec> fields = ImmutableMap.builder(); ClassName jsonAdapter = ClassName.get(TypeAdapter.class); Set<TypeName> seenTypes = Sets.newHashSet(); NameAllocator nameAllocator = new NameAllocator(); for (Property property : properties) { if (!property.shouldDeserialize() && !property.shouldSerialize()) { continue; } TypeName type = property.type.isPrimitive() ? property.type.box() : property.type; ParameterizedTypeName adp = ParameterizedTypeName.get(jsonAdapter, type); if (!seenTypes.contains(property.type)) { fields.put(property.type, FieldSpec.builder(adp, nameAllocator.newName(simpleName(property.type)) + "_adapter", PRIVATE, FINAL) .build()); seenTypes.add(property.type); } } return fields.build(); }
private ImmutableMap<TypeMirror, FieldSpec> getTypeAdapters(List<Property> properties) { Map<TypeMirror, FieldSpec> typeAdapters = new LinkedHashMap<>(); NameAllocator nameAllocator = new NameAllocator(); nameAllocator.newName("CREATOR"); for (Property property : properties) { if (property.typeAdapter != null && !typeAdapters.containsKey(property.typeAdapter)) { ClassName typeName = (ClassName) TypeName.get(property.typeAdapter); String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, typeName.simpleName()); name = nameAllocator.newName(name, typeName); typeAdapters.put(property.typeAdapter, FieldSpec.builder( typeName, NameAllocator.toJavaIdentifier(name), PRIVATE, STATIC, FINAL) .initializer("new $T()", typeName).build()); } } return ImmutableMap.copyOf(typeAdapters); }
private MethodSpec messageAdapterEncodedSize(NameAllocator nameAllocator, MessageType type, TypeName javaType, boolean useBuilder) { MethodSpec.Builder result = MethodSpec.methodBuilder("encodedSize") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(int.class) .addParameter(javaType, "value"); result.addCode("$["); String leading = "return"; for (Field field : type.fieldsAndOneOfFields()) { int fieldTag = field.tag(); String fieldName = nameAllocator.get(field); CodeBlock adapter = adapterFor(field); result.addCode("$L $L.encodedSizeWithTag($L, ", leading, adapter, fieldTag) .addCode((useBuilder ? "value.$L" : "$L(value)"), fieldName) .addCode(")"); leading = "\n+"; } if (useBuilder) { result.addCode("$L value.unknownFields().size()", leading); } result.addCode(";$]\n", leading); return result.build(); }
private MethodSpec messageAdapterEncode(NameAllocator nameAllocator, MessageType type, TypeName javaType, boolean useBuilder) { MethodSpec.Builder result = MethodSpec.methodBuilder("encode") .addAnnotation(Override.class) .addModifiers(PUBLIC) .addParameter(ProtoWriter.class, "writer") .addParameter(javaType, "value") .addException(IOException.class); for (Field field : type.fieldsAndOneOfFields()) { int fieldTag = field.tag(); CodeBlock adapter = adapterFor(field); result.addCode("$L.encodeWithTag(writer, $L, ", adapter, fieldTag) .addCode((useBuilder ? "value.$L" : "$L(value)"), nameAllocator.get(field)) .addCode(");\n"); } if (useBuilder) { result.addStatement("writer.writeBytes(value.unknownFields())"); } return result.build(); }
private CodeBlock decodeAndAssign(Field field, NameAllocator nameAllocator, boolean useBuilder) { String fieldName = nameAllocator.get(field); CodeBlock decode = CodeBlock.of("$L.decode(reader)", singleAdapterFor(field)); if (field.isRepeated()) { return useBuilder ? CodeBlock.of("builder.$L.add($L)", fieldName, decode) : CodeBlock.of("$L.add($L)", fieldName, decode); } else if (field.type().isMap()) { return useBuilder ? CodeBlock.of("builder.$L.putAll($L)", fieldName, decode) : CodeBlock.of("$L.putAll($L)", fieldName, decode); } else { return useBuilder ? CodeBlock.of("builder.$L($L)", fieldName, decode) : CodeBlock.of("$L = $L", fieldName, decode); } }
private MethodSpec messageFieldsConstructor(NameAllocator nameAllocator, MessageType type) { MethodSpec.Builder result = MethodSpec.constructorBuilder(); result.addModifiers(PUBLIC); result.addCode("this("); for (Field field : type.fieldsAndOneOfFields()) { TypeName javaType = fieldType(field); String fieldName = nameAllocator.get(field); ParameterSpec.Builder param = ParameterSpec.builder(javaType, fieldName); if (emitAndroid && field.isOptional()) { param.addAnnotation(NULLABLE); } result.addParameter(param.build()); result.addCode("$L, ", fieldName); } result.addCode("$T.EMPTY);\n", BYTE_STRING); return result.build(); }
static CodeBlock readValue(Types types, JsonProperty property, ParameterSpec json, FieldSpec field, FieldSpec key, NameAllocator nameAllocator) { //TODO Handle collections. TypeName type = getTypeNameFromProperty(property, types); CodeBlock.Builder builder = CodeBlock.builder(); if (type.equals(STRING)) { builder.addStatement("$N = $N.getString($N)", field, json, key); } else if (type.equals(TypeName.INT) || type.equals(TypeName.INT.box())) { builder.addStatement("$N = $N.getInt($N)", field, json, key); } else if (type.equals(TypeName.DOUBLE) || type.equals(TypeName.DOUBLE.box())) { builder.addStatement("$N = $N.getDouble($N)", field, json, key); } else if (type.equals(TypeName.FLOAT) || type.equals(TypeName.FLOAT.box())) { builder.addStatement("$N = (float) $N.getDouble($N)", field, json, key); } else if (type.equals(TypeName.BOOLEAN) || type.equals(TypeName.BOOLEAN.box())) { builder.addStatement("$N = $N.getBoolean($N)", field, json, key); } else if (type.equals(TypeName.LONG) || type.equals(TypeName.LONG.box())) { builder.addStatement("$N = $N.getLong($N)", field, json, key); } else if (type.equals(TypeName.SHORT) || type.equals(TypeName.SHORT.box())) { builder.addStatement("$N = (short) $N.getInt($N)", field, json, key); } else if (type.equals(TypeName.BYTE) || type.equals(TypeName.BYTE.box())) { builder.addStatement("$N = (byte) $N.getInt($N)", field, json, key); } else if (type.equals(TypeName.CHAR) || type.equals(TypeName.CHAR.box())) { FieldSpec tempVal = FieldSpec.builder(String.class, nameAllocator.newName("tempVal"), Modifier.FINAL).build(); builder.addStatement("$T $N = $N.getString($N)", tempVal.type, tempVal, json, key); builder.beginControlFlow("if(!$N.isEmpty())", tempVal); builder.addStatement("$N = $N.charAt(0)", field, tempVal); builder.endControlFlow(); } else if (type.equals(ENUM)) { builder.addStatement("$N = $T.valueOf($N.getString($N))", field, field.type, json, key); } else { throw new IllegalStateException(String.format("supportedType [%s] with not method.", type)); } return builder.build(); }
@Override public String generateClass(Context context, String className, String classToExtend, boolean isFinal) { List<JsonProperty> properties = JsonProperty.from(context); validateProperties(context.processingEnvironment(), properties); Map<String, TypeName> types = convertPropertiesToTypes(context.properties()); NameAllocator nameAllocator = new NameAllocator(); Map<TypeMirror, FieldSpec> typeAdapters = getTypeAdapters(properties, nameAllocator); TypeName superClass = TypeVariableName.get(classToExtend); TypeSpec.Builder subclass = TypeSpec.classBuilder(className) .superclass(superClass) .addMethod(generateConstructor(types)); if (generateReadMethod(context)) { subclass.addMethod( generateFromJson(context, properties, typeAdapters, nameAllocator.clone())); } Optional<ExecutableElement> writeMethod = getJsonWriteMethod(context); if (writeMethod.isPresent()) { subclass.addMethod(generateWriteToJson(context, writeMethod.get(), properties, typeAdapters, nameAllocator.clone())); } if (!typeAdapters.isEmpty()) { for (FieldSpec field : typeAdapters.values()) { subclass.addField(field); } } if (isFinal) { subclass.addModifiers(FINAL); } else { subclass.addModifiers(ABSTRACT); } return JavaFile.builder(context.packageName(), subclass.build()).build().toString(); }
private MethodSpec generateWriteToJson(Context context, ExecutableElement writeMethodElement, List<JsonProperty> properties, Map<TypeMirror, FieldSpec> typeAdapters, NameAllocator nameAllocator) { Set<Modifier> modifierSet = new TreeSet<>(writeMethodElement.getModifiers()); modifierSet.remove(ABSTRACT); MethodSpec.Builder builder = MethodSpec.methodBuilder(writeMethodElement.getSimpleName().toString()) .addAnnotation(Override.class) .addModifiers(modifierSet) .returns(JSON_OBJ_CLASS_NAME); FieldSpec json = FieldSpec.builder(JSON_OBJ_CLASS_NAME, nameAllocator.newName("json")).build(); builder.addStatement("$1T $2N = new $1T()", JSON_OBJ_CLASS_NAME, json); Types types = context.processingEnvironment().getTypeUtils(); for (JsonProperty prop : properties) { if (prop.typeAdapter != null && typeAdapters.containsKey(prop.typeAdapter)) { builder.addCode( JsonGeneratorUtils.writeWithAdapter(typeAdapters.get(prop.typeAdapter), json, prop)); } else { //TODO Discuss: Is null check needed? builder.beginControlFlow("try"); if (prop.nullable()) { builder.beginControlFlow("if ($N() != null)", prop.methodName); builder.addCode(JsonGeneratorUtils.writeValue(types, prop, json)); builder.endControlFlow(); } else { builder.addCode(JsonGeneratorUtils.writeValue(types, prop, json)); } builder.endControlFlow("catch($T e) {}", JSON_EXCEPTION); } } builder.addStatement("return $N", json); return builder.build(); }
private MethodSpec createValidationMethod(TypeName targetClassName, ImmutableMap<Property, FieldSpec> validators) { String valueName = "value"; ParameterSpec value = ParameterSpec.builder(targetClassName, valueName) .build(); MethodSpec.Builder validateMethod = MethodSpec.methodBuilder("validate") .addAnnotation(Override.class) .addModifiers(PUBLIC) .addParameter(value) .addException(ValidationException.class); // Go through validators NameAllocator allocator = new NameAllocator(); validators.entrySet() .stream() .filter(entry -> entry.getKey() .shouldValidate()) .forEach(entry -> { Property prop = entry.getKey(); FieldSpec validator = entry.getValue(); String name = allocator.newName(entry.getKey().methodName); validateMethod.addComment("Begin validation for \"$L()\"", prop.methodName) .addStatement("$T $L = $N.$L()", prop.type, name, value, prop.methodName) .addCode("\n"); extensions.stream() .sorted(Comparator.comparing(InspectorExtension::priority)) .filter(e -> e.applicable(prop)) .forEach(e -> { CodeBlock block = e.generateValidation(prop, name, value); if (block != null) { validateMethod.addComment("Validations contributed by $S", e.toString()) .addCode(block); } }); validateMethod.addStatement("$N.validate($L)", validator, name) .addCode("\n"); }); return validateMethod.build(); }
public static FieldSpec spec(NameAllocator nameAllocator, Types types, WeaveDescriptor classDescriptor, WeaveMethodDescriptor methodDescriptor) { // overload methods? String method = methodDescriptor.name(); TypeName targetType = TypeName.get(classDescriptor.element().asType()); TypeName returnType = TypeName.get(types.erasure(methodDescriptor.element().getReturnType())); List<? extends VariableElement> parameters = methodDescriptor.element().getParameters(); FieldSpec.Builder pointcutBuilder = FieldSpec.builder(StaticPointcut.class, nameAllocator.newName(method + "Pointcut")); pointcutBuilder.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL); StringBuilder format = new StringBuilder(); format.append("$T.create($S, $T.class, $T.class, $T.<Class<?>>asList("); for (int i = 0, len = parameters.size(); i < len; i++) { if (i != 0) { format.append(", "); } format.append("$T.class"); } format.append("))"); Object[] args = new Object[5 + parameters.size()]; args[0] = StaticPointcut.class; args[1] = method; args[2] = targetType; args[3] = returnType; args[4] = Arrays.class; for (int i = 0; i < parameters.size(); i++) { args[i + 5] = TypeName.get(types.erasure(parameters.get(i).asType())); } pointcutBuilder.initializer(format.toString(), args); return pointcutBuilder.build(); }
CodeBlock renderConstValue( final CodeBlock.Builder block, final NameAllocator allocator, final AtomicInteger scope, final ThriftType type, final ConstValueElement value) { return type.accept(new ConstRenderingVisitor(block, allocator, scope, type, value)); }
ConstRenderingVisitor( CodeBlock.Builder block, NameAllocator allocator, AtomicInteger scope, ThriftType type, ConstValueElement value) { this.block = block; this.allocator = allocator; this.scope = scope; this.type = type; this.value = value; }
public static String sanitizeParamName(String string) { String underscoresFixed = Splitter.on("_").splitToList(string).stream().map(StringUtils::capitalize) .collect(joining()); String identifier = uncapitalize(underscoresFixed) .replaceAll("[^A-Za-z0-9]", "") .replaceAll("^([0-9]+)", "_$1"); return new NameAllocator().newName(identifier); }
private MethodSpec createWriteMethod(TypeName autoValueClassName, ImmutableMap<Property, FieldSpec> adapters) { String writerName = "writer"; String valueName = "value"; ParameterSpec writer = ParameterSpec.builder(JsonWriter.class, writerName).build(); ParameterSpec value = ParameterSpec.builder(autoValueClassName, valueName).build(); MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("toJson") .addAnnotation(Override.class) .addModifiers(PUBLIC) .addParameter(writer) .addParameter(value) .addException(IOException.class); writeMethod.addStatement("$N.beginObject()", writer); NameAllocator nameAllocator = new NameAllocator(); nameAllocator.newName(writerName); nameAllocator.newName(valueName); for (Map.Entry<Property, FieldSpec> entry : adapters.entrySet()) { Property prop = entry.getKey(); FieldSpec field = entry.getValue(); nameAllocator.newName(prop.humanName, prop); if (prop.nullable()) { String name = nameAllocator.get(prop); writeMethod.addStatement("$T $N = $N.$N()", prop.type, name, value, prop.methodName); writeMethod.beginControlFlow("if ($N != null)", name); writeMethod.addStatement("$N.name($S)", writer, prop.serializedName()); writeMethod.addStatement("this.$N.toJson($N, $N)", field, writer, name); writeMethod.endControlFlow(); } else { writeMethod.addStatement("$N.name($S)", writer, prop.serializedName()); writeMethod.addStatement("this.$N.toJson($N, $N.$N())", field, writer, value, prop.methodName); } } writeMethod.addStatement("$N.endObject()", writer); return writeMethod.build(); }
public static ImmutableMap<ClassName, String> addColumnAdaptersToMethod( MethodSpec.Builder method, List<ColumnProperty> properties) { Map<ClassName, String> columnAdapters = new LinkedHashMap<>(); NameAllocator nameAllocator = new NameAllocator(); for (ColumnProperty property : properties) { ClassName adapter = property.columnAdapter(); if (adapter != null && !columnAdapters.containsKey(adapter)) { String name = nameAllocator.newName(toLowerCase(adapter.simpleName())); method.addStatement("$1T $2L = new $1T()", adapter, name); columnAdapters.put(adapter, name); } } return ImmutableMap.copyOf(columnAdapters); }
public String toString(final NameAllocator nameAllocator) { final StringBuilder stringBuilder = new StringBuilder(); if (list.size() > 0) { for (final Parameter parameter : list) { stringBuilder.append(nameAllocator.get(parameter.hashCode())).append(", "); } stringBuilder.setLength(stringBuilder.length() - 2); } return stringBuilder.toString(); }
private void addMethodCalls(final MethodSpec.Builder result, final Set<Parameter> existingParameters, final List<MethodCall> methodCalls) { final NameAllocator nameAllocator = new NameAllocator(); for (final MethodCall methodCall : methodCalls) { final ParameterList parameterList = methodCall.getParameterList(); this.addNecessaryParameterVariables(nameAllocator, result, existingParameters, parameterList); result.addStatement("$L.$L($L)", TARGET_VARIABLE_NAME, methodCall.getMethodName(), parameterList.toString(nameAllocator)); } }
@Override public NameAllocator load(Type type) throws Exception { NameAllocator nameAllocator = new NameAllocator(); if (type instanceof MessageType) { nameAllocator.newName("serialVersionUID", "serialVersionUID"); nameAllocator.newName("ADAPTER", "ADAPTER"); nameAllocator.newName("MESSAGE_OPTIONS", "MESSAGE_OPTIONS"); if (emitAndroid) { nameAllocator.newName("CREATOR", "CREATOR"); } ImmutableList<Field> fieldsAndOneOfFields = ((MessageType) type).fieldsAndOneOfFields(); Set<String> collidingNames = collidingFieldNames(fieldsAndOneOfFields); for (Field field : fieldsAndOneOfFields) { String suggestion = collidingNames.contains(field.name()) ? field.qualifiedName() : field.name(); nameAllocator.newName(suggestion, field); } } else if (type instanceof EnumType) { nameAllocator.newName("value", "value"); nameAllocator.newName("i", "i"); nameAllocator.newName("reader", "reader"); nameAllocator.newName("writer", "writer"); for (EnumConstant constant : ((EnumType) type).constants()) { nameAllocator.newName(constant.name(), constant); } } return nameAllocator; }
/** Returns a standalone adapter for {@code type}. */ public TypeSpec generateAdapterForCustomType(Type type) { NameAllocator nameAllocator = nameAllocators.getUnchecked(type); ClassName adapterTypeName = abstractAdapterName(type.type()); ClassName typeName = (ClassName) typeName(type.type()); TypeSpec.Builder adapter; if (type instanceof MessageType) { adapter = messageAdapter(nameAllocator, (MessageType) type, typeName, adapterTypeName, null) .toBuilder(); } else { adapter = enumAdapter(nameAllocator, (EnumType) type, typeName, adapterTypeName).toBuilder(); } if (adapterTypeName.enclosingClassName() != null) adapter.addModifiers(STATIC); for (Type nestedType : type.nestedTypes()) { if (profile.getAdapter(nestedType.type()) == null) { throw new IllegalArgumentException("Missing custom proto adapter for " + nestedType.type().enclosingTypeOrPackage() + "." + nestedType.type().simpleName() + " when enclosing proto has custom proto adapter."); } adapter.addType(generateAdapterForCustomType(nestedType)); } return adapter.build(); }
private MethodSpec messageEquals(NameAllocator nameAllocator, MessageType type) { NameAllocator localNameAllocator = nameAllocator.clone(); String otherName = localNameAllocator.newName("other"); String oName = localNameAllocator.newName("o"); TypeName javaType = typeName(type.type()); MethodSpec.Builder result = MethodSpec.methodBuilder("equals") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(boolean.class) .addParameter(Object.class, otherName); List<Field> fields = type.fieldsAndOneOfFields(); if (fields.isEmpty()) { result.addStatement("return $N instanceof $T", otherName, javaType); return result.build(); } result.addStatement("if ($N == this) return true", otherName); result.addStatement("if (!($N instanceof $T)) return false", otherName, javaType); result.addStatement("$T $N = ($T) $N", javaType, oName, javaType, otherName); result.addCode("$[return unknownFields().equals($N.unknownFields())", oName); for (Field field : fields) { String fieldName = localNameAllocator.get(field); if (field.isRequired() || field.isRepeated() || field.type().isMap()) { result.addCode("\n&& $1L.equals($2N.$1L)", fieldName, oName); } else { result.addCode("\n&& $1T.equals($2L, $3N.$2L)", Internal.class, fieldName, oName); } } result.addCode(";\n$]"); return result.build(); }
private MethodSpec messageHashCode(NameAllocator nameAllocator, MessageType type) { NameAllocator localNameAllocator = nameAllocator.clone(); String resultName = localNameAllocator.newName("result"); MethodSpec.Builder result = MethodSpec.methodBuilder("hashCode") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(int.class); List<Field> fields = type.fieldsAndOneOfFields(); if (fields.isEmpty()) { result.addStatement("return unknownFields().hashCode()"); return result.build(); } result.addStatement("int $N = super.hashCode", resultName); result.beginControlFlow("if ($N == 0)", resultName); result.addStatement("$N = unknownFields().hashCode()", resultName); for (Field field : fields) { String fieldName = localNameAllocator.get(field); result.addCode("$1N = $1N * 37 + ", resultName); if (field.isRepeated() || field.isRequired() || field.type().isMap()) { result.addStatement("$L.hashCode()", fieldName); } else { result.addStatement("($1L != null ? $1L.hashCode() : 0)", fieldName); } } result.addStatement("super.hashCode = $N", resultName); result.endControlFlow(); result.addStatement("return $N", resultName); return result.build(); }
private MethodSpec messageToString(NameAllocator nameAllocator, MessageType type) { NameAllocator localNameAllocator = nameAllocator.clone(); MethodSpec.Builder result = MethodSpec.methodBuilder("toString") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(String.class); String builderName = localNameAllocator.newName("builder"); result.addStatement("$1T $2N = new $1T()", StringBuilder.class, builderName); for (Field field : type.fieldsAndOneOfFields()) { String fieldName = nameAllocator.get(field); if (field.isRepeated() || field.type().isMap()) { result.addCode("if (!$N.isEmpty()) ", fieldName); } else if (!field.isRequired()) { result.addCode("if ($N != null) ", fieldName); } if (field.isRedacted()) { result.addStatement("$N.append(\", $N=██\")", builderName, field.name()); } else { result.addStatement("$N.append(\", $N=\").append($L)", builderName, field.name(), fieldName); } } result.addStatement("return builder.replace(0, 2, \"$L{\").append('}').toString()", type.type().simpleName()); return result.build(); }
private MethodSpec builderNoArgsConstructor(NameAllocator nameAllocator, MessageType type) { MethodSpec.Builder result = MethodSpec.constructorBuilder().addModifiers(PUBLIC); for (Field field : type.fieldsAndOneOfFields()) { String fieldName = nameAllocator.get(field); CodeBlock initialValue = initialValue(field); if (initialValue != null) { result.addStatement("$L = $L", fieldName, initialValue); } } return result.build(); }
private MethodSpec newBuilder(NameAllocator nameAllocator, MessageType message) { NameAllocator localNameAllocator = nameAllocator.clone(); String builderName = localNameAllocator.newName("builder"); ClassName javaType = (ClassName) typeName(message.type()); ClassName builderJavaType = javaType.nestedClass("Builder"); MethodSpec.Builder result = MethodSpec.methodBuilder("newBuilder") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(builderJavaType) .addStatement("$1T $2L = new $1T()", builderJavaType, builderName); List<Field> fields = message.fieldsAndOneOfFields(); for (Field field : fields) { String fieldName = localNameAllocator.get(field); if (field.isRepeated() || field.type().isMap()) { result.addStatement("$1L.$2L = $3T.copyOf($2S, $2L)", builderName, fieldName, Internal.class); } else { result.addStatement("$1L.$2L = $2L", builderName, fieldName); } } result.addStatement("$L.addUnknownFields(unknownFields())", builderName); result.addStatement("return $L", builderName); return result.build(); }
private MethodSpec setter( NameAllocator nameAllocator, TypeName builderType, OneOf oneOf, Field field) { TypeName javaType = fieldType(field); String fieldName = nameAllocator.get(field); MethodSpec.Builder result = MethodSpec.methodBuilder(fieldName) .addModifiers(PUBLIC) .addParameter(javaType, fieldName) .returns(builderType); if (!field.documentation().isEmpty()) { result.addJavadoc("$L\n", sanitizeJavadoc(field.documentation())); } if (field.isDeprecated()) { result.addAnnotation(Deprecated.class); } if (field.isRepeated() || field.type().isMap()) { result.addStatement("$T.checkElementsNotNull($L)", Internal.class, fieldName); } result.addStatement("this.$L = $L", fieldName, fieldName); if (oneOf != null) { for (Field other : oneOf.fields()) { if (field != other) { result.addStatement("this.$L = null", nameAllocator.get(other)); } } } result.addStatement("return this"); return result.build(); }
private MethodSpec builderBuild( NameAllocator nameAllocator, MessageType message, ClassName javaType) { MethodSpec.Builder result = MethodSpec.methodBuilder("build") .addAnnotation(Override.class) .addModifiers(PUBLIC) .returns(javaType); List<Field> requiredFields = message.getRequiredFields(); if (!requiredFields.isEmpty()) { CodeBlock.Builder conditionals = CodeBlock.builder().add("$["); CodeBlock.Builder missingArgs = CodeBlock.builder(); for (int i = 0; i < requiredFields.size(); i++) { Field requiredField = requiredFields.get(i); if (i > 0) conditionals.add("\n|| "); conditionals.add("$L == null", nameAllocator.get(requiredField)); if (i > 0) missingArgs.add(",\n"); missingArgs.add("$1L, $2S", nameAllocator.get(requiredField), requiredField.name()); } result.beginControlFlow("if ($L)", conditionals.add("$]").build()) .addStatement("throw $T.missingRequiredFields($L)", Internal.class, missingArgs.build()) .endControlFlow(); } result.addCode("return new $T(", javaType); for (Field field : message.fieldsAndOneOfFields()) { result.addCode("$L, ", nameAllocator.get(field)); } result.addCode("super.buildUnknownFields());\n"); return result.build(); }
private MethodSpec createPropertyMethod(Element element) { if (TypeKind.ARRAY.equals(element.asType().getKind())) { NameAllocator names = new NameAllocator(); String name = names.newName(element.getSimpleName().toString()); String array = names.newName("array"); String value = names.newName("value"); String size = names.newName("size"); TypeMirror componentType = TypeMapper.asArrayType(element.asType()).getComponentType(); CodeBlock code = CodeBlock.builder() .beginControlFlow("if ($T.isClient())", ClassNames.GWT_SHARED_HELPER) .addStatement("JsArray<$T> $L", componentType, array) .beginControlFlow("if (this.object.$L != null)", name) .addStatement("Object $L = this.object.$L", value, name) .addStatement("$L = (JsArray<$T>) $L", array, componentType, value) .nextControlFlow("else") .addStatement("$L = new JsArray<>()", array) .addStatement("Object $L = $L", value, array) .addStatement("this.object.$L = ($T[]) $L", name, componentType, value) .endControlFlow() .beginControlFlow("for (int i = 0; i < $L.length; i++)", name) .addStatement("$L.push($L[i])", array, name) .endControlFlow() .nextControlFlow("else") .beginControlFlow("if (this.object.$L == null)", name) .addStatement("this.object.$L = new $T[0]", name, componentType) .endControlFlow() .addStatement("this.object.$L = $T.concat(" + "\n$T.stream(this.object.$L), $T.stream($L))" + "\n.toArray($L -> new $T[$L])", name, Stream.class, Arrays.class, name, Arrays.class, name, size, componentType, size) .endControlFlow() .addStatement("return this") .build(); return MethodSpec.methodBuilder(getWithMethodName(element)) .addModifiers(Modifier.PUBLIC) .addAnnotation(AnnotationSpec.builder(SuppressWarnings.class) .addMember("value", "$S", "unchecked") .build()) .returns(getBuilderName(element.getEnclosingElement())) .addParameter(ParameterSpec.builder(TypeName.get(element.asType()), element.getSimpleName().toString()) .build()) .varargs() .addCode(code) .build(); } else { return MethodSpec.methodBuilder(getWithMethodName(element)) .addModifiers(Modifier.PUBLIC) .returns(getBuilderName(element.getEnclosingElement())) .addParameter(ParameterSpec.builder(TypeName.get(element.asType()), element.getSimpleName().toString()) .build()) .addCode(CodeBlock.builder() .addStatement("this.object.$L = $L", element.getSimpleName(), element.getSimpleName()) .addStatement("return this") .build()) .build(); } }
public State(AidlProcessor.Environment environment, NameAllocator allocator, ContractHasher digest) { this.environment = environment; this.allocator = allocator; this.digest = digest; }
private MethodSpec buildCallCtor(ServiceMethod method, TypeName callbackTypeName) { NameAllocator allocator = new NameAllocator(); AtomicInteger scope = new AtomicInteger(0); MethodSpec.Builder ctor = MethodSpec.constructorBuilder() .addStatement( "super($S, $T.$L, callback)", method.name(), TypeNames.TMESSAGE_TYPE, method.oneWay() ? "ONEWAY" : "CALL"); for (Field field : method.parameters()) { String fieldName = fieldNamer.getName(field); TypeName javaType = typeResolver.getJavaClass(field.type().getTrueType()); ctor.addParameter(javaType, fieldName); if (field.required() && field.defaultValue() == null) { ctor.addStatement("if ($L == null) throw new NullPointerException($S)", fieldName, fieldName); ctor.addStatement("this.$1L = $1L", fieldName); } else if (field.defaultValue() != null) { ctor.beginControlFlow("if ($L != null)", fieldName); ctor.addStatement("this.$1L = $1L", fieldName); ctor.nextControlFlow("else"); CodeBlock.Builder init = CodeBlock.builder(); constantBuilder.generateFieldInitializer( init, allocator, scope, "this." + fieldName, field.type().getTrueType(), field.defaultValue(), false); ctor.addCode(init.build()); ctor.endControlFlow(); } else { ctor.addStatement("this.$1L = $1L", fieldName); } } ctor.addParameter(callbackTypeName, "callback"); return ctor.build(); }
@SuppressWarnings("PMD.CyclomaticComplexity") private void addNecessaryParameterVariables(final NameAllocator nameAllocator, final MethodSpec.Builder result, final Set<Parameter> existingParameters, final ParameterList parameterList) { for (final Parameter parameter : parameterList) { final boolean isNotPresent = !existingParameters.contains(parameter); if (isNotPresent) { String parameterName; try { parameterName = nameAllocator.get(parameter.hashCode()); // The only way to know whether a name has already been generated for that hashCode or not } catch (final IllegalArgumentException ignore) { parameterName = nameAllocator.newName(parameter.getName(), parameter.hashCode()); } if (AnnotatedParameter.INTENT_DATA == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getIntentData$L($L)", AnnotatedParameter.INTENT_DATA.type, parameterName, INTENT_HELPER, parameter.preCondition.getSuffix(), Parameter.INTENT); existingParameters.add(parameter); } else if (AnnotatedParameter.BOOLEAN == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraBoolean($L, $S, $L)", AnnotatedParameter.BOOLEAN.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.BYTE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraByte($L, $S, (byte) $L)", AnnotatedParameter.BYTE.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.CHAR == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraChar($L, $S, (char) $L)", AnnotatedParameter.CHAR.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.DOUBLE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraDouble($L, $S, $L)", AnnotatedParameter.DOUBLE.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.FLOAT == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraFloat($L, $S, $Lf)", AnnotatedParameter.FLOAT.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.INT == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraInt($L, $S, $L)", AnnotatedParameter.INT.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.LONG == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraLong($L, $S, $LL)", AnnotatedParameter.LONG.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.SHORT == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraShort($L, $S, (short) $L)", AnnotatedParameter.SHORT.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.STRING == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraString($L, $S, $S)", AnnotatedParameter.STRING.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.CHAR_SEQUENCE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraCharSequence($L, $S, $L)", AnnotatedParameter.CHAR_SEQUENCE.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.BUNDLE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraBundle($L, $S, $L)", AnnotatedParameter.BUNDLE.type, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.SERIALIZABLE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraSerializable($L, $S, $L)", parameter.className, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } else if (AnnotatedParameter.PARCELABLE == parameter.annotatedParameter) { result.addStatement("final $T $L = $T.getExtraParcelable($L, $S, $L)", parameter.className, parameterName, INTENT_HELPER, Parameter.INTENT, parameter.getKey(), parameter.getDefaultValue()); existingParameters.add(parameter); } } } }
private String fieldName(ProtoType type, Field field) { MessageType messageType = (MessageType) schema.getType(type); NameAllocator names = nameAllocators.getUnchecked(messageType); return names.get(field); }
private FieldSpec defaultField(NameAllocator nameAllocator, Field field, TypeName fieldType) { String defaultFieldName = "DEFAULT_" + nameAllocator.get(field).toUpperCase(Locale.US); return FieldSpec.builder(fieldType, defaultFieldName, PUBLIC, STATIC, FINAL) .initializer(defaultValue(field)) .build(); }