Search in sources :

Example 6 with Field

use of com.squareup.wire.schema.Field in project wire by square.

the class JavaGenerator method messageAdapter.

private TypeSpec messageAdapter(NameAllocator nameAllocator, MessageType type, ClassName javaType, ClassName adapterJavaType, ClassName builderType) {
    boolean useBuilder = builderType != null;
    TypeSpec.Builder adapter = TypeSpec.classBuilder(adapterJavaType.simpleName()).superclass(adapterOf(javaType));
    if (useBuilder) {
        adapter.addModifiers(PRIVATE, STATIC, FINAL);
    } else {
        adapter.addModifiers(PUBLIC, ABSTRACT);
    }
    adapter.addMethod(MethodSpec.constructorBuilder().addModifiers(PUBLIC).addStatement("super($T.LENGTH_DELIMITED, $T.class, $S, $T.$L, null, $S)", FieldEncoding.class, javaType, type.getType().getTypeUrl(), Syntax.class, type.getSyntax().name(), type.getLocation().getPath()).build());
    if (!useBuilder) {
        MethodSpec.Builder fromProto = MethodSpec.methodBuilder("fromProto").addModifiers(PUBLIC, ABSTRACT).returns(javaType);
        for (Field field : type.getFieldsAndOneOfFields()) {
            TypeName fieldType = fieldType(field);
            String fieldName = nameAllocator.get(field);
            fromProto.addParameter(fieldType, fieldName);
            adapter.addMethod(MethodSpec.methodBuilder(fieldName).addModifiers(PUBLIC, ABSTRACT).addParameter(javaType, "value").returns(fieldType).build());
        }
        adapter.addMethod(fromProto.build());
    }
    adapter.addMethod(messageAdapterEncodedSize(nameAllocator, type, javaType, useBuilder));
    adapter.addMethod(messageAdapterEncode(nameAllocator, type, javaType, useBuilder, false));
    adapter.addMethod(messageAdapterEncode(nameAllocator, type, javaType, useBuilder, true));
    adapter.addMethod(messageAdapterDecode(nameAllocator, type, javaType, useBuilder, builderType));
    adapter.addMethod(messageAdapterRedact(nameAllocator, type, javaType, useBuilder, builderType));
    for (Field field : type.getFieldsAndOneOfFields()) {
        if (field.getType().isMap()) {
            TypeName adapterType = adapterOf(fieldType(field));
            String fieldName = nameAllocator.get(field);
            adapter.addField(FieldSpec.builder(adapterType, fieldName, PRIVATE).build());
            // Map adapters have to be lazy in order to avoid a circular reference when its value type
            // is the same as its enclosing type.
            adapter.addMethod(mapAdapter(nameAllocator, adapterType, fieldName, field.getType()));
        }
    }
    return adapter.build();
}
Also used : WireField(com.squareup.wire.WireField) Field(com.squareup.wire.schema.Field) TypeName(com.squareup.javapoet.TypeName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) MethodSpec(com.squareup.javapoet.MethodSpec) ByteString(okio.ByteString) JvmLanguages.builtInAdapterString(com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 7 with Field

use of com.squareup.wire.schema.Field in project wire by square.

the class JavaGenerator method generateMessage.

private TypeSpec generateMessage(MessageType type) {
    boolean constructorTakesAllFields = constructorTakesAllFields(type);
    NameAllocator nameAllocator = nameAllocators.getUnchecked(type);
    ClassName javaType = (ClassName) typeName(type.getType());
    ClassName builderJavaType = javaType.nestedClass("Builder");
    TypeSpec.Builder builder = TypeSpec.classBuilder(javaType.simpleName());
    builder.addModifiers(PUBLIC, FINAL);
    if (javaType.enclosingClassName() != null) {
        builder.addModifiers(STATIC);
    }
    if (!type.getDocumentation().isEmpty()) {
        builder.addJavadoc("$L\n", sanitizeJavadoc(type.getDocumentation()));
    }
    for (AnnotationSpec annotation : optionAnnotations(type.getOptions())) {
        builder.addAnnotation(annotation);
    }
    if (type.isDeprecated()) {
        builder.addAnnotation(Deprecated.class);
    }
    ClassName messageType = emitAndroid ? ANDROID_MESSAGE : MESSAGE;
    builder.superclass(messageOf(messageType, javaType, builderJavaType));
    String adapterName = nameAllocator.get("ADAPTER");
    String protoAdapterName = "ProtoAdapter_" + javaType.simpleName();
    String protoAdapterClassName = nameAllocator.newName(protoAdapterName);
    ClassName adapterJavaType = javaType.nestedClass(protoAdapterClassName);
    builder.addField(messageAdapterField(adapterName, javaType, adapterJavaType, type.getType(), type.getSyntax()));
    if (emitAndroid) {
        TypeName creatorType = creatorOf(javaType);
        String creatorName = nameAllocator.get("CREATOR");
        builder.addField(FieldSpec.builder(creatorType, creatorName, PUBLIC, STATIC, FINAL).initializer("$T.newCreator($L)", ANDROID_MESSAGE, adapterName).build());
    }
    builder.addField(FieldSpec.builder(TypeName.LONG, nameAllocator.get("serialVersionUID")).addModifiers(PRIVATE, STATIC, FINAL).initializer("$LL", 0L).build());
    for (Field field : type.getFieldsAndOneOfFields()) {
        TypeName fieldJavaType = fieldType(field);
        Field.EncodeMode encodeMode = field.getEncodeMode();
        if ((field.getType().isScalar() || isEnum(field.getType())) && !field.getType().equals(ProtoType.STRUCT_NULL) && encodeMode != Field.EncodeMode.REPEATED && encodeMode != Field.EncodeMode.PACKED && encodeMode != Field.EncodeMode.OMIT_IDENTITY) {
            builder.addField(defaultField(nameAllocator, field, fieldJavaType));
        }
        String fieldName = nameAllocator.get(field);
        FieldSpec.Builder fieldBuilder = FieldSpec.builder(fieldJavaType, fieldName, PUBLIC, FINAL);
        if (!field.getDocumentation().isEmpty()) {
            fieldBuilder.addJavadoc("$L\n", sanitizeJavadoc(field.getDocumentation()));
        }
        for (AnnotationSpec annotation : optionAnnotations(field.getOptions())) {
            fieldBuilder.addAnnotation(annotation);
        }
        fieldBuilder.addAnnotation(wireFieldAnnotation(nameAllocator, field, type));
        if (field.isExtension()) {
            fieldBuilder.addJavadoc("Extension source: $L\n", field.getLocation().withPathOnly());
        }
        if (field.isDeprecated()) {
            fieldBuilder.addAnnotation(Deprecated.class);
        }
        if (emitAndroidAnnotations && encodeMode == Field.EncodeMode.NULL_IF_ABSENT) {
            fieldBuilder.addAnnotation(NULLABLE);
        }
        builder.addField(fieldBuilder.build());
    }
    if (constructorTakesAllFields) {
        builder.addMethod(messageFieldsConstructor(nameAllocator, type));
    }
    builder.addMethod(messageConstructor(nameAllocator, type, builderJavaType));
    builder.addMethod(newBuilder(nameAllocator, type));
    builder.addMethod(messageEquals(nameAllocator, type));
    builder.addMethod(messageHashCode(nameAllocator, type));
    if (!emitCompact) {
        builder.addMethod(messageToString(nameAllocator, type));
    }
    builder.addType(builder(nameAllocator, type, javaType, builderJavaType));
    for (Type nestedType : type.getNestedTypes()) {
        builder.addType(generateType(nestedType));
    }
    if (!emitCompact) {
        // Add the ProtoAdapter implementation at the very bottom since it's ugly serialization code.
        builder.addType(messageAdapter(nameAllocator, type, javaType, adapterJavaType, builderJavaType));
    }
    return builder.build();
}
Also used : NameAllocator(com.squareup.javapoet.NameAllocator) TypeName(com.squareup.javapoet.TypeName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) ByteString(okio.ByteString) JvmLanguages.builtInAdapterString(com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString) AnnotationSpec(com.squareup.javapoet.AnnotationSpec) FieldSpec(com.squareup.javapoet.FieldSpec) WireField(com.squareup.wire.WireField) Field(com.squareup.wire.schema.Field) JvmLanguages.annotationTargetType(com.squareup.wire.schema.internal.JvmLanguages.annotationTargetType) Type(com.squareup.wire.schema.Type) ProtoType(com.squareup.wire.schema.ProtoType) MessageType(com.squareup.wire.schema.MessageType) ElementType(java.lang.annotation.ElementType) EnclosingType(com.squareup.wire.schema.EnclosingType) EnumType(com.squareup.wire.schema.EnumType) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 8 with Field

use of com.squareup.wire.schema.Field in project wire by square.

the class JavaGenerator method newBuilder.

// Example:
// 
// @Override
// public Message.Builder newBuilder() {
// Builder builder = new Builder();
// builder.optional_int32 = optional_int32;
// ...
// builder.addUnknownFields(unknownFields());
// return builder;
// }
private MethodSpec newBuilder(NameAllocator nameAllocator, MessageType message) {
    NameAllocator localNameAllocator = nameAllocator.clone();
    String builderName = localNameAllocator.newName("builder");
    ClassName javaType = (ClassName) typeName(message.getType());
    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.getFieldsAndOneOfFields();
    for (Field field : fields) {
        String fieldName = localNameAllocator.get(field);
        if (field.isRepeated() || field.getType().isMap()) {
            result.addStatement("$1L.$2L = $3T.copyOf($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();
}
Also used : NameAllocator(com.squareup.javapoet.NameAllocator) WireField(com.squareup.wire.WireField) Field(com.squareup.wire.schema.Field) MethodSpec(com.squareup.javapoet.MethodSpec) ClassName(com.squareup.javapoet.ClassName) ByteString(okio.ByteString) JvmLanguages.builtInAdapterString(com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString)

Example 9 with Field

use of com.squareup.wire.schema.Field in project wire by square.

the class JavaGenerator method messageHashCode.

// Example:
// 
// @Override
// public int hashCode() {
// int result = hashCode;
// if (result == 0) {
// result = unknownFields().hashCode();
// result = result * 37 + (f != null ? f.hashCode() : 0);
// hashCode = result;
// }
// return result;
// }
// 
// For repeated fields, the final "0" in the example above changes to a "1"
// in order to be the same as the system hash code for an empty list.
// 
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.getFieldsAndOneOfFields();
    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);
        TypeName typeName = fieldType(field);
        result.addCode("$1N = $1N * 37 + ", resultName);
        if (typeName == TypeName.BOOLEAN) {
            result.addStatement("$T.hashCode($N)", Boolean.class, fieldName);
        } else if (typeName == TypeName.INT) {
            result.addStatement("$T.hashCode($N)", Integer.class, fieldName);
        } else if (typeName == TypeName.LONG) {
            result.addStatement("$T.hashCode($N)", Long.class, fieldName);
        } else if (typeName == TypeName.FLOAT) {
            result.addStatement("$T.hashCode($N)", Float.class, fieldName);
        } else if (typeName == TypeName.DOUBLE) {
            result.addStatement("$T.hashCode($N)", Double.class, fieldName);
        } else if (field.isRequired() || field.isRepeated() || field.getType().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();
}
Also used : NameAllocator(com.squareup.javapoet.NameAllocator) WireField(com.squareup.wire.WireField) Field(com.squareup.wire.schema.Field) TypeName(com.squareup.javapoet.TypeName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) MethodSpec(com.squareup.javapoet.MethodSpec) ByteString(okio.ByteString) JvmLanguages.builtInAdapterString(com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString)

Example 10 with Field

use of com.squareup.wire.schema.Field in project wire by square.

the class JavaGenerator method get.

public static JavaGenerator get(Schema schema) {
    Map<ProtoType, TypeName> nameToJavaName = new LinkedHashMap<>();
    Map<ProtoMember, TypeName> memberToJavaName = new LinkedHashMap<>();
    for (ProtoFile protoFile : schema.getProtoFiles()) {
        String javaPackage = javaPackage(protoFile);
        putAll(nameToJavaName, javaPackage, null, protoFile.getTypes());
        for (Service service : protoFile.getServices()) {
            ClassName className = ClassName.get(javaPackage, service.type().getSimpleName());
            nameToJavaName.put(service.type(), className);
        }
        for (Extend extend : protoFile.getExtendList()) {
            if (annotationTargetType(extend) == null)
                continue;
            for (Field field : extend.getFields()) {
                if (!eligibleAsAnnotationMember(schema, field))
                    continue;
                ProtoMember protoMember = field.getMember();
                String simpleName = camelCase(protoMember.getSimpleName(), true) + "Option";
                ClassName className = ClassName.get(javaPackage, simpleName);
                memberToJavaName.put(protoMember, className);
            }
        }
    }
    nameToJavaName.putAll(BUILT_IN_TYPES_MAP);
    return new JavaGenerator(schema, nameToJavaName, memberToJavaName, new Profile(), false, /* emitAndroid */
    false, /* emitAndroidAnnotations */
    false, /* emitCompact */
    false, /* emitDeclaredOptions */
    false);
}
Also used : TypeName(com.squareup.javapoet.TypeName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) ProtoFile(com.squareup.wire.schema.ProtoFile) Service(com.squareup.wire.schema.Service) ByteString(okio.ByteString) JvmLanguages.builtInAdapterString(com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString) LinkedHashMap(java.util.LinkedHashMap) ProtoType(com.squareup.wire.schema.ProtoType) WireField(com.squareup.wire.WireField) Field(com.squareup.wire.schema.Field) Extend(com.squareup.wire.schema.Extend) ClassName(com.squareup.javapoet.ClassName) ProtoMember(com.squareup.wire.schema.ProtoMember)

Aggregations

WireField (com.squareup.wire.WireField)23 Field (com.squareup.wire.schema.Field)23 ByteString (okio.ByteString)19 JvmLanguages.builtInAdapterString (com.squareup.wire.schema.internal.JvmLanguages.builtInAdapterString)17 MethodSpec (com.squareup.javapoet.MethodSpec)15 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)12 TypeName (com.squareup.javapoet.TypeName)12 CodeBlock (com.squareup.javapoet.CodeBlock)10 WildcardTypeName (com.squareup.javapoet.WildcardTypeName)10 NameAllocator (com.squareup.javapoet.NameAllocator)7 ClassName (com.squareup.javapoet.ClassName)4 Internal (com.squareup.wire.internal.Internal)4 ParameterSpec (com.squareup.javapoet.ParameterSpec)3 TypeSpec (com.squareup.javapoet.TypeSpec)3 OneOf (com.squareup.wire.schema.OneOf)3 ProtoMember (com.squareup.wire.schema.ProtoMember)3 ArrayList (java.util.ArrayList)3 LinkedHashMap (java.util.LinkedHashMap)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ProtoFile (com.squareup.wire.schema.ProtoFile)2