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();
}
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();
}
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();
}
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();
}
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);
}
Aggregations