Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2910,15 +2910,15 @@ public AllTypes decode(ProtoReader reader) throws IOException {
}
break;
}
case 17: builder.nested_message(NestedMessage.ADAPTER.decode(reader)); break;
case 18: builder.any(AnyMessage.ADAPTER.decode(reader)); break;
case 19: builder.duration(ProtoAdapter.DURATION.decode(reader)); break;
case 20: builder.struct(ProtoAdapter.STRUCT_MAP.decode(reader)); break;
case 21: builder.list_value(ProtoAdapter.STRUCT_LIST.decode(reader)); break;
case 22: builder.value(ProtoAdapter.STRUCT_VALUE.decode(reader)); break;
case 17: builder.nested_message(Internal.decodeMessageOrMerge(NestedMessage.ADAPTER, reader, builder.nested_message)); break;
case 18: builder.any(Internal.decodeMessageOrMerge(AnyMessage.ADAPTER, reader, builder.any)); break;
case 19: builder.duration(Internal.decodeMessageOrMerge(ProtoAdapter.DURATION, reader, builder.duration)); break;
case 20: builder.struct(Internal.decodeMessageOrMerge(ProtoAdapter.STRUCT_MAP, reader, builder.struct)); break;
case 21: builder.list_value(Internal.decodeMessageOrMerge(ProtoAdapter.STRUCT_LIST, reader, builder.list_value)); break;
case 22: builder.value(Internal.decodeMessageOrMerge(ProtoAdapter.STRUCT_VALUE, reader, builder.value)); break;
case 23: builder.null_value((Void) ProtoAdapter.STRUCT_NULL.decode(reader)); break;
case 24: builder.empty(ProtoAdapter.EMPTY.decode(reader)); break;
case 25: builder.timestamp(ProtoAdapter.INSTANT.decode(reader)); break;
case 24: builder.empty(Internal.decodeMessageOrMerge(ProtoAdapter.EMPTY, reader, builder.empty)); break;
case 25: builder.timestamp(Internal.decodeMessageOrMerge(ProtoAdapter.INSTANT, reader, builder.timestamp)); break;
case 101: builder.opt_int32(ProtoAdapter.INT32.decode(reader)); break;
case 102: builder.opt_uint32(ProtoAdapter.UINT32.decode(reader)); break;
case 103: builder.opt_sint32(ProtoAdapter.SINT32.decode(reader)); break;
Expand Down
405 changes: 203 additions & 202 deletions wire-golden-files/src/main/kotlin/HundredsFields.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.squareup.wire.ReverseProtoWriter
import com.squareup.wire.Syntax.PROTO_2
import com.squareup.wire.WireField
import com.squareup.wire.`internal`.JvmField
import com.squareup.wire.`internal`.decodeMessageOrMerge
import com.squareup.wire.`internal`.sanitize
import kotlin.Any
import kotlin.AssertionError
Expand Down Expand Up @@ -118,7 +119,7 @@ public class OuterOpaqueType(
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> inner_opaque_type_1 = ProtoAdapter.BYTES.decode(reader)
2 -> inner_opaque_type_2 = InnerOpaqueType2.ADAPTER.decode(reader)
2 -> inner_opaque_type_2 = decodeMessageOrMerge(InnerOpaqueType2.ADAPTER, reader, inner_opaque_type_2)
else -> reader.readUnknownField(tag)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.squareup.wire.`internal`.JvmStatic
import com.squareup.wire.`internal`.JvmSynthetic
import com.squareup.wire.`internal`.LongArrayList
import com.squareup.wire.`internal`.checkElementsNotNull
import com.squareup.wire.`internal`.decodeMessageOrMerge
import com.squareup.wire.`internal`.decodePrimitive_double
import com.squareup.wire.`internal`.decodePrimitive_fixed32
import com.squareup.wire.`internal`.decodePrimitive_fixed64
Expand Down Expand Up @@ -3945,7 +3946,7 @@ public class AllTypes private constructor(
} catch (e: ProtoAdapter.EnumConstantNotFoundException) {
reader.addUnknownField(tag, FieldEncoding.VARINT, e.value.toLong())
}
17 -> builder.opt_nested_message(NestedMessage.ADAPTER.decode(reader))
17 -> builder.opt_nested_message(decodeMessageOrMerge(NestedMessage.ADAPTER, reader, builder.opt_nested_message))
101 -> builder.req_int32(ProtoAdapter.INT32.decode(reader))
102 -> builder.req_uint32(ProtoAdapter.UINT32.decode(reader))
103 -> builder.req_sint32(ProtoAdapter.SINT32.decode(reader))
Expand All @@ -3966,7 +3967,7 @@ public class AllTypes private constructor(
} catch (e: ProtoAdapter.EnumConstantNotFoundException) {
reader.addUnknownField(tag, FieldEncoding.VARINT, e.value.toLong())
}
117 -> builder.req_nested_message(NestedMessage.ADAPTER.decode(reader))
117 -> builder.req_nested_message(decodeMessageOrMerge(NestedMessage.ADAPTER, reader, builder.req_nested_message))
201 -> rep_int32.add(ProtoAdapter.INT32.decode(reader))
202 -> rep_uint32.add(ProtoAdapter.UINT32.decode(reader))
203 -> rep_sint32.add(ProtoAdapter.SINT32.decode(reader))
Expand Down Expand Up @@ -4239,7 +4240,7 @@ public class AllTypes private constructor(
} catch (e: ProtoAdapter.EnumConstantNotFoundException) {
reader.addUnknownField(tag, FieldEncoding.VARINT, e.value.toLong())
}
1_017 -> builder.ext_opt_nested_message(NestedMessage.ADAPTER.decode(reader))
1_017 -> builder.ext_opt_nested_message(decodeMessageOrMerge(NestedMessage.ADAPTER, reader, builder.ext_opt_nested_message))
1_101 -> ext_rep_int32.add(ProtoAdapter.INT32.decode(reader))
1_102 -> ext_rep_uint32.add(ProtoAdapter.UINT32.decode(reader))
1_103 -> ext_rep_sint32.add(ProtoAdapter.SINT32.decode(reader))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.squareup.wire.ReverseProtoWriter
import com.squareup.wire.Syntax.PROTO_2
import com.squareup.wire.WireField
import com.squareup.wire.`internal`.JvmField
import com.squareup.wire.`internal`.decodeMessageOrMerge
import kotlin.Any
import kotlin.Boolean
import kotlin.Deprecated
Expand Down Expand Up @@ -110,7 +111,7 @@ public class MutablePacket(
val payload = mutableListOf<MutablePayload>()
val unknownFields = reader.forEachTag { tag ->
when (tag) {
1 -> header_ = MutableHeader.ADAPTER.decode(reader)
1 -> header_ = decodeMessageOrMerge(MutableHeader.ADAPTER, reader, header_)
2 -> payload.add(MutablePayload.ADAPTER.decode(reader))
else -> reader.readUnknownField(tag)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,21 @@ private CodeBlock decodeAndAssign(Field field, NameAllocator nameAllocator, bool
return useBuilder
? CodeBlock.of("builder.$L.putAll($L)", fieldName, decode)
: CodeBlock.of("$L.putAll($L)", fieldName, decode);
} else if (schema.getType(field.getType()) instanceof MessageType && !field.isOneOf()) {
CodeBlock adapter = singleAdapterFor(field, nameAllocator);
return useBuilder
? CodeBlock.of(
"builder.$L($T.decodeMessageOrMerge($L, reader, builder.$L))",
fieldName,
Internal.class,
adapter,
fieldName)
: CodeBlock.of(
"$L = $T.decodeMessageOrMerge($L, reader, $L)",
fieldName,
Internal.class,
adapter,
fieldName);
} else {
return useBuilder
? field.getType().equals(ProtoType.STRUCT_NULL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public void generateAbstractAdapter() throws Exception {
+ " long token = reader.beginMessage();\n"
+ " for (int tag; (tag = reader.nextTag()) != -1;) {\n"
+ " switch (tag) {\n"
+ " case 1: field = Foo.ADAPTER.decode(reader); break;\n"
+ " case 1: field = Internal.decodeMessageOrMerge(Foo.ADAPTER, reader, field); break;\n"
+ " case 2: bars.putAll(barsAdapter().decode(reader)); break;\n"
+ " case 3: numbers.add(ProtoAdapter.INT32.decode(reader)); break;\n"
+ " case 4: {\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,14 @@ class KotlinGenerator private constructor(

field.isRepeated -> CodeBlock.of("%N.add(%L)", fieldName, decode)
field.isMap -> CodeBlock.of("%N.putAll(%L)", fieldName, decode)
field.type!!.isMessage && !field.isOneOf -> {
val decodeMessageOrMerge = MemberName("com.squareup.wire.internal", "decodeMessageOrMerge")
if (buildersOnly) {
CodeBlock.of("builder.%N(%M(%L, reader, builder.%N))", fieldName, decodeMessageOrMerge, adapterName, fieldName)
} else {
CodeBlock.of("%N = %M(%L, reader, %N)", fieldName, decodeMessageOrMerge, adapterName, fieldName)
}
}
else -> CodeBlock.of(if (buildersOnly) "builder.%N(%L)" else "%N·= %L", fieldName, decode)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1832,7 +1832,7 @@ class KotlinGeneratorTest {
| val unknownFields = reader.forEachTag { tag ->
| when (tag) {
| 1 -> name = ProtoAdapter.STRING.decode(reader)
| 2 -> location = StringPointAdapter.INSTANCE.decode(reader)
| 2 -> location = decodeMessageOrMerge(StringPointAdapter.INSTANCE, reader, location)
| else -> reader.readUnknownField(tag)
| }
| }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,11 @@ message InteropBoxOneOf {
sint32 f = 6;
}
}

message SubInteropRepeatedUint {
repeated uint32 repeated_values = 1 [packed = true];
}

message InteropRepeatedUint {
optional SubInteropRepeatedUint sub_message = 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,12 @@ message InteropBoxOneOf {
sint32 f = 6;
}
}

message SubInteropRepeatedUint {
repeated uint32 repeated_values = 1 [packed = true];
}

message InteropRepeatedUint {
optional SubInteropRepeatedUint sub_message = 1;
}

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import okio.ByteString.Companion.decodeHex
import org.junit.Test
import squareup.proto2.java.empty.EmptyLength as EmptyLengthJ
import squareup.proto2.java.interop.InteropMessage as InteropMessageJ
import squareup.proto2.java.interop.InteropRepeatedUint as InteropRepeatedUintJ2
import squareup.proto2.java.interop.InteropTest.InteropRepeatedUint as InteropRepeatedUintP2
import squareup.proto2.java.interop.InteropTest.SubInteropRepeatedUint as SubInteropRepeatedUintP2
import squareup.proto2.java.interop.SubInteropRepeatedUint as SubInteropRepeatedUintJ2
import squareup.proto2.java.interop.type.EnumProto2 as EnumProto2J
import squareup.proto2.java.interop.type.MessageProto2 as MessageProto2J
import squareup.proto2.kotlin.MapTypes
Expand All @@ -49,10 +53,12 @@ import squareup.proto2.kotlin.interop.InteropMessageOuterClass.extRepProto2Enum
import squareup.proto2.kotlin.interop.InteropMessageOuterClass.extRepProto2Message
import squareup.proto2.kotlin.interop.InteropMessageOuterClass.extRepProto3Enum
import squareup.proto2.kotlin.interop.InteropMessageOuterClass.extRepProto3Message
import squareup.proto2.kotlin.interop.InteropRepeatedUint as InteropRepeatedUintK2
import squareup.proto2.kotlin.interop.Quilt
import squareup.proto2.kotlin.interop.QuiltColor
import squareup.proto2.kotlin.interop.QuiltContainer
import squareup.proto2.kotlin.interop.RepeatedEnum
import squareup.proto2.kotlin.interop.SubInteropRepeatedUint as SubInteropRepeatedUintK2
import squareup.proto2.kotlin.interop.type.EnumProto2 as EnumProto2K
import squareup.proto2.kotlin.interop.type.InteropTypes.EnumProto2
import squareup.proto2.kotlin.interop.type.InteropTypes.MessageProto2
Expand Down Expand Up @@ -183,6 +189,35 @@ class Proto2WireProtocCompatibilityTests {
assertThat(mapTypeWire.map_string_string[""]).isEqualTo("ed")
}

@Test fun decodingRepeatedEntries() {
// ── 1 ┐
// ├─ 1: 3
// ╰- 1: 3
val byteArray = byteArrayOf(10, 3, 10, 1, 3, 10, 3, 10, 1, 3)
assertThat(InteropRepeatedUintP2.parseFrom(byteArray))
.isEqualTo(
InteropRepeatedUintP2.newBuilder()
.setSubMessage(
SubInteropRepeatedUintP2.newBuilder().addAllRepeatedValues(listOf(3, 3)).build(),
)
.build(),
)
assertThat(InteropRepeatedUintK2.ADAPTER.decode(byteArray)).isEqualTo(
InteropRepeatedUintK2.Builder()
.sub_message(
SubInteropRepeatedUintK2.Builder().repeated_values(listOf(3, 3)).build(),
)
.build(),
)
assertThat(InteropRepeatedUintJ2.ADAPTER.decode(byteArray)).isEqualTo(
InteropRepeatedUintJ2.Builder()
.sub_message(
SubInteropRepeatedUintJ2.Builder().repeated_values(listOf(3, 3)).build(),
)
.build(),
)
}

/**
* The TS-proto library encodes enums differently from Wire or Protoc. Protoc is fine with this,
* but it causes Wire to crash. The fix is to make Wire accept this format also.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.squareup.wire.ProtoWriter
import com.squareup.wire.ReverseProtoWriter
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import okio.Buffer

// Methods for generated code use only. Not subject to public API rules.

Expand Down Expand Up @@ -347,6 +348,29 @@ fun encodeArray_double(array: DoubleArray, writer: ReverseProtoWriter, tag: Int)
}
}

/**
* Decodes a message from [reader], merging with [existing] if not null.
* Per the proto specification, when an embedded message field appears multiple times, the values
* are merged: repeated fields are concatenated, singular fields take the later value.
*/
fun <E> decodeMessageOrMerge(adapter: ProtoAdapter<E>, reader: ProtoReader, existing: E?): E {
if (existing == null) return adapter.decode(reader)
val bytes = reader.readBytes()
val buffer = Buffer()
adapter.encode(buffer, existing)
buffer.write(bytes)
return adapter.decode(buffer)
}

fun <E> decodeMessageOrMerge(adapter: ProtoAdapter<E>, reader: ProtoReader32, existing: E?): E {
if (existing == null) return adapter.decode(reader)
val bytes = reader.readBytes()
val buffer = Buffer()
adapter.encode(buffer, existing)
buffer.write(bytes)
return adapter.decode(buffer)
}

fun decodePrimitive_double(reader: ProtoReader32): Double = Double.fromBits(reader.readFixed64())
fun decodePrimitive_double(reader: ProtoReader): Double = Double.fromBits(reader.readFixed64())
fun decodePrimitive_fixed32(reader: ProtoReader32): Int = reader.readFixed32()
Expand Down
Loading