Skip to content

Commit

Permalink
Start work for OmitIdentityInJava + add java struct tests (square#1635)
Browse files Browse the repository at this point in the history
* Start work for OmitIdentityInJava + add java struct tests

* Add default to switch because I don't know Java

* Clean import and switch
  • Loading branch information
oldergod authored Jul 14, 2020
1 parent 76ac03e commit d12a503
Show file tree
Hide file tree
Showing 6 changed files with 328 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import okio.ByteString;
Expand Down Expand Up @@ -927,15 +928,25 @@ private MethodSpec messageAdapterEncodedSize(NameAllocator nameAllocator, Messag
.returns(int.class)
.addParameter(javaType, "value");

// TODO(benoit) Let's use an aggregator instead of chaining everything.
result.addCode("$[");
String leading = "return";
for (Field field : type.getFieldsAndOneOfFields()) {
int fieldTag = field.getTag();
String fieldName = nameAllocator.get(field);
CodeBlock adapter = adapterFor(field, nameAllocator);
result.addCode("$L $L.encodedSizeWithTag($L, ", leading, adapter, fieldTag)
result.addCode("$L ", leading);
boolean omitIdentity = field.getEncodeMode().equals(Field.EncodeMode.OMIT_IDENTITY);
if (omitIdentity) {
result.addCode("($T.equals(value.$L, $L) ? 0\n : ", ClassName.get(Objects.class),
fieldName, identityValue(field));
}
result.addCode("$L.encodedSizeWithTag($L, ", adapter, fieldTag)
.addCode((useBuilder ? "value.$L" : "$L(value)"), fieldName)
.addCode(")");
if (omitIdentity) {
result.addCode(")");
}
leading = "\n+";
}
if (useBuilder) {
Expand All @@ -958,8 +969,13 @@ private MethodSpec messageAdapterEncode(NameAllocator nameAllocator, MessageType
for (Field field : type.getFieldsAndOneOfFields()) {
int fieldTag = field.getTag();
CodeBlock adapter = adapterFor(field, nameAllocator);
String fieldName = nameAllocator.get(field);
if (field.getEncodeMode().equals(Field.EncodeMode.OMIT_IDENTITY)) {
result.addCode("if (!$T.equals(value.$L, $L)) ", ClassName.get(Objects.class),
fieldName, identityValue(field));
}
result.addCode("$L.encodeWithTag(writer, $L, ", adapter, fieldTag)
.addCode((useBuilder ? "value.$L" : "$L(value)"), nameAllocator.get(field))
.addCode((useBuilder ? "value.$L" : "$L(value)"), fieldName)
.addCode(");\n");
}

Expand Down Expand Up @@ -1791,6 +1807,61 @@ private CodeBlock fieldInitializer(ProtoType type, @Nullable Object value) {
}
}

private CodeBlock identityValue(Field field) {
switch (field.getEncodeMode()) {
case MAP:
return CodeBlock.of("$T.emptyMap()", Collections.class);
case REPEATED:
case PACKED:
return CodeBlock.of("$T.emptyList()", Collections.class);
case NULL_IF_ABSENT:
return CodeBlock.of("null");
case OMIT_IDENTITY:
ProtoType protoType = field.getType();
Type type = schema.getType(protoType);
if (protoType.equals(ProtoType.STRUCT_NULL)) {
return CodeBlock.of("null");
} else if (field.isOneOf()) {
return CodeBlock.of("null");
} else if (protoType.isScalar()) {
if (protoType.equals(ProtoType.BOOL)) {
return CodeBlock.of("false");
} else if (protoType.equals(ProtoType.STRING)) {
return CodeBlock.of("\"\"");
} else if (protoType.equals(ProtoType.BYTES)) {
return CodeBlock.of("$T.$L", ByteString.class, "EMPTY");
} else if (protoType.equals(ProtoType.DOUBLE)) {
return CodeBlock.of("0.0");
} else if (protoType.equals(ProtoType.FLOAT)) {
return CodeBlock.of("0f");
} else if (protoType.equals(ProtoType.FIXED64)
|| protoType.equals(ProtoType.INT64)
|| protoType.equals(ProtoType.SFIXED64)
|| protoType.equals(ProtoType.SINT64)
|| protoType.equals(ProtoType.UINT64)) {
return CodeBlock.of("0L");
} else if (protoType.equals(ProtoType.FIXED32)
|| protoType.equals(ProtoType.INT32)
|| protoType.equals(ProtoType.SFIXED32)
|| protoType.equals(ProtoType.SINT32)
|| protoType.equals(ProtoType.UINT32)) {
return CodeBlock.of("0");
} else {
throw new IllegalArgumentException("Unexpected scalar proto type: " + protoType);
}
} else if (type instanceof MessageType) {
return CodeBlock.of("null");
} else if (type instanceof EnumType) {
return CodeBlock.of("$T.$L", typeName(protoType),
((EnumType) type).constant(0).getName());
}
case REQUIRED:
default:
throw new IllegalArgumentException(
"No identity value for field: " + field + "(" + field.getEncodeMode() + ")");
}
}

static int valueToInt(@Nullable Object value) {
if (value == null) return 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import kotlin.Unit;
import okio.ByteString;

Expand Down Expand Up @@ -2119,13 +2120,14 @@ public ProtoAdapter_NestedMessage() {

@Override
public int encodedSize(NestedMessage value) {
return ProtoAdapter.INT32.encodedSizeWithTag(1, value.a)
return (Objects.equals(value.a, 0) ? 0
: ProtoAdapter.INT32.encodedSizeWithTag(1, value.a))
+ value.unknownFields().size();
}

@Override
public void encode(ProtoWriter writer, NestedMessage value) throws IOException {
ProtoAdapter.INT32.encodeWithTag(writer, 1, value.a);
if (!Objects.equals(value.a, 0)) ProtoAdapter.INT32.encodeWithTag(writer, 1, value.a);
writer.writeBytes(value.unknownFields());
}

Expand Down Expand Up @@ -2185,31 +2187,56 @@ public ProtoAdapter_AllTypes() {

@Override
public int encodedSize(AllTypes value) {
return ProtoAdapter.INT32.encodedSizeWithTag(1, value.int32)
+ ProtoAdapter.UINT32.encodedSizeWithTag(2, value.uint32)
+ ProtoAdapter.SINT32.encodedSizeWithTag(3, value.sint32)
+ ProtoAdapter.FIXED32.encodedSizeWithTag(4, value.fixed32)
+ ProtoAdapter.SFIXED32.encodedSizeWithTag(5, value.sfixed32)
+ ProtoAdapter.INT64.encodedSizeWithTag(6, value.int64)
+ ProtoAdapter.UINT64.encodedSizeWithTag(7, value.uint64)
+ ProtoAdapter.SINT64.encodedSizeWithTag(8, value.sint64)
+ ProtoAdapter.FIXED64.encodedSizeWithTag(9, value.fixed64)
+ ProtoAdapter.SFIXED64.encodedSizeWithTag(10, value.sfixed64)
+ ProtoAdapter.BOOL.encodedSizeWithTag(11, value.bool)
+ ProtoAdapter.FLOAT.encodedSizeWithTag(12, value.float_)
+ ProtoAdapter.DOUBLE.encodedSizeWithTag(13, value.double_)
+ ProtoAdapter.STRING.encodedSizeWithTag(14, value.string)
+ ProtoAdapter.BYTES.encodedSizeWithTag(15, value.bytes)
+ NestedEnum.ADAPTER.encodedSizeWithTag(16, value.nested_enum)
+ NestedMessage.ADAPTER.encodedSizeWithTag(17, value.nested_message)
+ AnyMessage.ADAPTER.encodedSizeWithTag(18, value.any)
+ ProtoAdapter.DURATION.encodedSizeWithTag(19, value.duration)
+ ProtoAdapter.STRUCT_MAP.encodedSizeWithTag(20, value.struct)
+ ProtoAdapter.STRUCT_LIST.encodedSizeWithTag(21, value.list_value)
+ ProtoAdapter.STRUCT_VALUE.encodedSizeWithTag(22, value.value)
+ ProtoAdapter.STRUCT_NULL.encodedSizeWithTag(23, value.null_value)
+ ProtoAdapter.EMPTY.encodedSizeWithTag(24, value.empty)
+ ProtoAdapter.INSTANT.encodedSizeWithTag(25, value.timestamp)
return (Objects.equals(value.int32, 0) ? 0
: ProtoAdapter.INT32.encodedSizeWithTag(1, value.int32))
+ (Objects.equals(value.uint32, 0) ? 0
: ProtoAdapter.UINT32.encodedSizeWithTag(2, value.uint32))
+ (Objects.equals(value.sint32, 0) ? 0
: ProtoAdapter.SINT32.encodedSizeWithTag(3, value.sint32))
+ (Objects.equals(value.fixed32, 0) ? 0
: ProtoAdapter.FIXED32.encodedSizeWithTag(4, value.fixed32))
+ (Objects.equals(value.sfixed32, 0) ? 0
: ProtoAdapter.SFIXED32.encodedSizeWithTag(5, value.sfixed32))
+ (Objects.equals(value.int64, 0L) ? 0
: ProtoAdapter.INT64.encodedSizeWithTag(6, value.int64))
+ (Objects.equals(value.uint64, 0L) ? 0
: ProtoAdapter.UINT64.encodedSizeWithTag(7, value.uint64))
+ (Objects.equals(value.sint64, 0L) ? 0
: ProtoAdapter.SINT64.encodedSizeWithTag(8, value.sint64))
+ (Objects.equals(value.fixed64, 0L) ? 0
: ProtoAdapter.FIXED64.encodedSizeWithTag(9, value.fixed64))
+ (Objects.equals(value.sfixed64, 0L) ? 0
: ProtoAdapter.SFIXED64.encodedSizeWithTag(10, value.sfixed64))
+ (Objects.equals(value.bool, false) ? 0
: ProtoAdapter.BOOL.encodedSizeWithTag(11, value.bool))
+ (Objects.equals(value.float_, 0f) ? 0
: ProtoAdapter.FLOAT.encodedSizeWithTag(12, value.float_))
+ (Objects.equals(value.double_, 0.0) ? 0
: ProtoAdapter.DOUBLE.encodedSizeWithTag(13, value.double_))
+ (Objects.equals(value.string, "") ? 0
: ProtoAdapter.STRING.encodedSizeWithTag(14, value.string))
+ (Objects.equals(value.bytes, ByteString.EMPTY) ? 0
: ProtoAdapter.BYTES.encodedSizeWithTag(15, value.bytes))
+ (Objects.equals(value.nested_enum, NestedEnum.UNKNOWN) ? 0
: NestedEnum.ADAPTER.encodedSizeWithTag(16, value.nested_enum))
+ (Objects.equals(value.nested_message, null) ? 0
: NestedMessage.ADAPTER.encodedSizeWithTag(17, value.nested_message))
+ (Objects.equals(value.any, null) ? 0
: AnyMessage.ADAPTER.encodedSizeWithTag(18, value.any))
+ (Objects.equals(value.duration, null) ? 0
: ProtoAdapter.DURATION.encodedSizeWithTag(19, value.duration))
+ (Objects.equals(value.struct, null) ? 0
: ProtoAdapter.STRUCT_MAP.encodedSizeWithTag(20, value.struct))
+ (Objects.equals(value.list_value, null) ? 0
: ProtoAdapter.STRUCT_LIST.encodedSizeWithTag(21, value.list_value))
+ (Objects.equals(value.value, null) ? 0
: ProtoAdapter.STRUCT_VALUE.encodedSizeWithTag(22, value.value))
+ (Objects.equals(value.null_value, null) ? 0
: ProtoAdapter.STRUCT_NULL.encodedSizeWithTag(23, value.null_value))
+ (Objects.equals(value.empty, null) ? 0
: ProtoAdapter.EMPTY.encodedSizeWithTag(24, value.empty))
+ (Objects.equals(value.timestamp, null) ? 0
: ProtoAdapter.INSTANT.encodedSizeWithTag(25, value.timestamp))
+ ProtoAdapter.INT32.asRepeated().encodedSizeWithTag(201, value.rep_int32)
+ ProtoAdapter.UINT32.asRepeated().encodedSizeWithTag(202, value.rep_uint32)
+ ProtoAdapter.SINT32.asRepeated().encodedSizeWithTag(203, value.rep_sint32)
Expand Down Expand Up @@ -2276,31 +2303,31 @@ public int encodedSize(AllTypes value) {

@Override
public void encode(ProtoWriter writer, AllTypes value) throws IOException {
ProtoAdapter.INT32.encodeWithTag(writer, 1, value.int32);
ProtoAdapter.UINT32.encodeWithTag(writer, 2, value.uint32);
ProtoAdapter.SINT32.encodeWithTag(writer, 3, value.sint32);
ProtoAdapter.FIXED32.encodeWithTag(writer, 4, value.fixed32);
ProtoAdapter.SFIXED32.encodeWithTag(writer, 5, value.sfixed32);
ProtoAdapter.INT64.encodeWithTag(writer, 6, value.int64);
ProtoAdapter.UINT64.encodeWithTag(writer, 7, value.uint64);
ProtoAdapter.SINT64.encodeWithTag(writer, 8, value.sint64);
ProtoAdapter.FIXED64.encodeWithTag(writer, 9, value.fixed64);
ProtoAdapter.SFIXED64.encodeWithTag(writer, 10, value.sfixed64);
ProtoAdapter.BOOL.encodeWithTag(writer, 11, value.bool);
ProtoAdapter.FLOAT.encodeWithTag(writer, 12, value.float_);
ProtoAdapter.DOUBLE.encodeWithTag(writer, 13, value.double_);
ProtoAdapter.STRING.encodeWithTag(writer, 14, value.string);
ProtoAdapter.BYTES.encodeWithTag(writer, 15, value.bytes);
NestedEnum.ADAPTER.encodeWithTag(writer, 16, value.nested_enum);
NestedMessage.ADAPTER.encodeWithTag(writer, 17, value.nested_message);
AnyMessage.ADAPTER.encodeWithTag(writer, 18, value.any);
ProtoAdapter.DURATION.encodeWithTag(writer, 19, value.duration);
ProtoAdapter.STRUCT_MAP.encodeWithTag(writer, 20, value.struct);
ProtoAdapter.STRUCT_LIST.encodeWithTag(writer, 21, value.list_value);
ProtoAdapter.STRUCT_VALUE.encodeWithTag(writer, 22, value.value);
ProtoAdapter.STRUCT_NULL.encodeWithTag(writer, 23, value.null_value);
ProtoAdapter.EMPTY.encodeWithTag(writer, 24, value.empty);
ProtoAdapter.INSTANT.encodeWithTag(writer, 25, value.timestamp);
if (!Objects.equals(value.int32, 0)) ProtoAdapter.INT32.encodeWithTag(writer, 1, value.int32);
if (!Objects.equals(value.uint32, 0)) ProtoAdapter.UINT32.encodeWithTag(writer, 2, value.uint32);
if (!Objects.equals(value.sint32, 0)) ProtoAdapter.SINT32.encodeWithTag(writer, 3, value.sint32);
if (!Objects.equals(value.fixed32, 0)) ProtoAdapter.FIXED32.encodeWithTag(writer, 4, value.fixed32);
if (!Objects.equals(value.sfixed32, 0)) ProtoAdapter.SFIXED32.encodeWithTag(writer, 5, value.sfixed32);
if (!Objects.equals(value.int64, 0L)) ProtoAdapter.INT64.encodeWithTag(writer, 6, value.int64);
if (!Objects.equals(value.uint64, 0L)) ProtoAdapter.UINT64.encodeWithTag(writer, 7, value.uint64);
if (!Objects.equals(value.sint64, 0L)) ProtoAdapter.SINT64.encodeWithTag(writer, 8, value.sint64);
if (!Objects.equals(value.fixed64, 0L)) ProtoAdapter.FIXED64.encodeWithTag(writer, 9, value.fixed64);
if (!Objects.equals(value.sfixed64, 0L)) ProtoAdapter.SFIXED64.encodeWithTag(writer, 10, value.sfixed64);
if (!Objects.equals(value.bool, false)) ProtoAdapter.BOOL.encodeWithTag(writer, 11, value.bool);
if (!Objects.equals(value.float_, 0f)) ProtoAdapter.FLOAT.encodeWithTag(writer, 12, value.float_);
if (!Objects.equals(value.double_, 0.0)) ProtoAdapter.DOUBLE.encodeWithTag(writer, 13, value.double_);
if (!Objects.equals(value.string, "")) ProtoAdapter.STRING.encodeWithTag(writer, 14, value.string);
if (!Objects.equals(value.bytes, ByteString.EMPTY)) ProtoAdapter.BYTES.encodeWithTag(writer, 15, value.bytes);
if (!Objects.equals(value.nested_enum, NestedEnum.UNKNOWN)) NestedEnum.ADAPTER.encodeWithTag(writer, 16, value.nested_enum);
if (!Objects.equals(value.nested_message, null)) NestedMessage.ADAPTER.encodeWithTag(writer, 17, value.nested_message);
if (!Objects.equals(value.any, null)) AnyMessage.ADAPTER.encodeWithTag(writer, 18, value.any);
if (!Objects.equals(value.duration, null)) ProtoAdapter.DURATION.encodeWithTag(writer, 19, value.duration);
if (!Objects.equals(value.struct, null)) ProtoAdapter.STRUCT_MAP.encodeWithTag(writer, 20, value.struct);
if (!Objects.equals(value.list_value, null)) ProtoAdapter.STRUCT_LIST.encodeWithTag(writer, 21, value.list_value);
if (!Objects.equals(value.value, null)) ProtoAdapter.STRUCT_VALUE.encodeWithTag(writer, 22, value.value);
if (!Objects.equals(value.null_value, null)) ProtoAdapter.STRUCT_NULL.encodeWithTag(writer, 23, value.null_value);
if (!Objects.equals(value.empty, null)) ProtoAdapter.EMPTY.encodeWithTag(writer, 24, value.empty);
if (!Objects.equals(value.timestamp, null)) ProtoAdapter.INSTANT.encodeWithTag(writer, 25, value.timestamp);
ProtoAdapter.INT32.asRepeated().encodeWithTag(writer, 201, value.rep_int32);
ProtoAdapter.UINT32.asRepeated().encodeWithTag(writer, 202, value.rep_uint32);
ProtoAdapter.SINT32.asRepeated().encodeWithTag(writer, 203, value.rep_sint32);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.lang.String;
import java.lang.StringBuilder;
import java.util.List;
import java.util.Objects;
import okio.ByteString;

/**
Expand Down Expand Up @@ -419,15 +420,17 @@ public ProtoAdapter_PhoneNumber() {

@Override
public int encodedSize(PhoneNumber value) {
return ProtoAdapter.STRING.encodedSizeWithTag(1, value.number)
+ PhoneType.ADAPTER.encodedSizeWithTag(2, value.type)
return (Objects.equals(value.number, "") ? 0
: ProtoAdapter.STRING.encodedSizeWithTag(1, value.number))
+ (Objects.equals(value.type, PhoneType.MOBILE) ? 0
: PhoneType.ADAPTER.encodedSizeWithTag(2, value.type))
+ value.unknownFields().size();
}

@Override
public void encode(ProtoWriter writer, PhoneNumber value) throws IOException {
ProtoAdapter.STRING.encodeWithTag(writer, 1, value.number);
PhoneType.ADAPTER.encodeWithTag(writer, 2, value.type);
if (!Objects.equals(value.number, "")) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.number);
if (!Objects.equals(value.type, PhoneType.MOBILE)) PhoneType.ADAPTER.encodeWithTag(writer, 2, value.type);
writer.writeBytes(value.unknownFields());
}

Expand Down Expand Up @@ -471,9 +474,12 @@ public ProtoAdapter_Person() {

@Override
public int encodedSize(Person value) {
return ProtoAdapter.STRING.encodedSizeWithTag(1, value.name)
+ ProtoAdapter.INT32.encodedSizeWithTag(2, value.id)
+ ProtoAdapter.STRING.encodedSizeWithTag(3, value.email)
return (Objects.equals(value.name, "") ? 0
: ProtoAdapter.STRING.encodedSizeWithTag(1, value.name))
+ (Objects.equals(value.id, 0) ? 0
: ProtoAdapter.INT32.encodedSizeWithTag(2, value.id))
+ (Objects.equals(value.email, "") ? 0
: ProtoAdapter.STRING.encodedSizeWithTag(3, value.email))
+ PhoneNumber.ADAPTER.asRepeated().encodedSizeWithTag(4, value.phones)
+ ProtoAdapter.STRING.asRepeated().encodedSizeWithTag(5, value.aliases)
+ ProtoAdapter.INT32.encodedSizeWithTag(6, value.foo)
Expand All @@ -483,9 +489,9 @@ public int encodedSize(Person value) {

@Override
public void encode(ProtoWriter writer, Person value) throws IOException {
ProtoAdapter.STRING.encodeWithTag(writer, 1, value.name);
ProtoAdapter.INT32.encodeWithTag(writer, 2, value.id);
ProtoAdapter.STRING.encodeWithTag(writer, 3, value.email);
if (!Objects.equals(value.name, "")) ProtoAdapter.STRING.encodeWithTag(writer, 1, value.name);
if (!Objects.equals(value.id, 0)) ProtoAdapter.INT32.encodeWithTag(writer, 2, value.id);
if (!Objects.equals(value.email, "")) ProtoAdapter.STRING.encodeWithTag(writer, 3, value.email);
PhoneNumber.ADAPTER.asRepeated().encodeWithTag(writer, 4, value.phones);
ProtoAdapter.STRING.asRepeated().encodeWithTag(writer, 5, value.aliases);
ProtoAdapter.INT32.encodeWithTag(writer, 6, value.foo);
Expand Down
12 changes: 12 additions & 0 deletions wire-protoc-compatibility-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ wire {

kotlin {
javaInterop = true
includes = [
'squareup.proto2.kotlin.*',
'squareup.proto3.kotlin.*',
'google.protobuf.*',
]
}

java {
includes = [
'squareup.proto2.java.*',
'squareup.proto3.java.*',
]
}
}

Expand Down
Loading

0 comments on commit d12a503

Please sign in to comment.