Skip to content

Commit 1b34fcc

Browse files
author
Egor Andreevich
authored
Merge pull request square#1213 from square/egorand/190929/parse-test-kotlin
Copy ParseTest to common Kotlin
2 parents 6d86fe7 + 43d7e6b commit 1b34fcc

File tree

9 files changed

+515
-2
lines changed

9 files changed

+515
-2
lines changed

gen-tests.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ task generateKotlinTests(type: JavaExec) {
169169
'simple_message.proto',
170170
'external_message.proto',
171171
'unknown_fields.proto',
172+
'edge_cases.proto',
172173
]
173174
}
174175

wire-runtime/src/jsMain/kotlin/com/squareup/wire/internal/-Platform.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ actual interface Serializable
2222

2323
actual abstract class ObjectStreamException : IOException()
2424

25-
actual class ProtocolException actual constructor(host: String) : IOException()
25+
actual class ProtocolException actual constructor(host: String) : IOException(host)
2626

2727
@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
2828
actual inline fun <T> MutableList<T>.toUnmodifiableList(): List<T> = this

wire-runtime/src/nativeMain/kotlin/com/squareup/wire/internal/-Platform.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ actual interface Serializable
2222

2323
actual abstract class ObjectStreamException : IOException()
2424

25-
actual class ProtocolException actual constructor(host: String) : IOException()
25+
actual class ProtocolException actual constructor(host: String) : IOException(host)
2626

2727
@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
2828
actual inline fun <T> MutableList<T>.toUnmodifiableList(): List<T> = this
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2014 Square Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.squareup.wire
17+
18+
import com.squareup.wire.internal.ProtocolException
19+
import com.squareup.wire.protos.kotlin.edgecases.OneBytesField
20+
import com.squareup.wire.protos.kotlin.edgecases.OneField
21+
import com.squareup.wire.protos.kotlin.edgecases.Recursive
22+
import okio.ByteString
23+
import okio.ByteString.Companion.decodeHex
24+
import okio.EOFException
25+
import okio.IOException
26+
import kotlin.test.Test
27+
import kotlin.test.assertEquals
28+
import kotlin.test.assertNotEquals
29+
import kotlin.test.fail
30+
31+
class ParseTest {
32+
@Test
33+
fun unknownTagIgnored() {
34+
// tag 1 / type 0: 456
35+
// tag 2 / type 0: 789
36+
val data = "08c803109506".decodeHex()
37+
val oneField = OneField.ADAPTER.decode(data.toByteArray())
38+
val expected = OneField(opt_int32 = 456)
39+
assertNotEquals(expected, oneField)
40+
assertEquals(expected, oneField.copy(unknownFields = ByteString.EMPTY))
41+
}
42+
43+
@Test
44+
fun unknownTypeThrowsIOException() {
45+
// tag 1 / type 0: 456
46+
// tag 2 / type 7: 789
47+
val data = "08c803179506".decodeHex()
48+
try {
49+
OneField.ADAPTER.decode(data.toByteArray())
50+
fail()
51+
} catch (expected: ProtocolException) {
52+
assertEquals("Unexpected field encoding: 7", expected.message)
53+
}
54+
}
55+
56+
@Test
57+
fun truncatedMessageThrowsEOFException() {
58+
// tag 1 / 4-byte length delimited string: 0x000000 (3 bytes)
59+
val data = "0a04000000".decodeHex()
60+
try {
61+
OneBytesField.ADAPTER.decode(data.toByteArray())
62+
fail()
63+
} catch (expected: EOFException) {
64+
}
65+
}
66+
67+
@Test
68+
fun lastValueWinsForRepeatedValueOfNonrepeatedField() {
69+
// tag 1 / type 0: 456
70+
// tag 1 / type 0: 789
71+
val data = "08c803089506".decodeHex()
72+
val oneField = OneField.ADAPTER.decode(data.toByteArray())
73+
assertEquals(oneField, OneField(opt_int32 = 789))
74+
}
75+
76+
@Test
77+
fun upToRecursionLimit() {
78+
// tag 2: nested message (64 times)
79+
// tag 1: signed varint32 456
80+
val data = ("127e127c127a12781276127412721270126e126c126a12681266126"
81+
+ "412621260125e125c125a12581256125412521250124e124c124a12481246124412421240123e123c123a123"
82+
+ "81236123412321230122e122c122a12281226122412221220121e121c121a12181216121412121210120e120"
83+
+ "c120a1208120612041202120008c803").decodeHex()
84+
val recursive = Recursive.ADAPTER.decode(data.toByteArray())
85+
assertEquals(456, recursive.value!!.toInt())
86+
}
87+
88+
@Test
89+
fun overRecursionLimitThrowsIOException() {
90+
// tag 2: nested message (65 times)
91+
// tag 1: signed varint32 456
92+
val data = ("128001127e127c127a12781276127412721270126e126c126a12681"
93+
+ "266126412621260125e125c125a12581256125412521250124e124c124a12481246124412421240123e123c1"
94+
+ "23a12381236123412321230122e122c122a12281226122412221220121e121c121a121812161214121212101"
95+
+ "20e120c120a1208120612041202120008c803").decodeHex()
96+
try {
97+
Recursive.ADAPTER.decode(data.toByteArray())
98+
fail()
99+
} catch (expected: IOException) {
100+
assertEquals("Wire recursion limit exceeded", expected.message)
101+
}
102+
}
103+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Code generated by Wire protocol buffer compiler, do not edit.
2+
// Source file: edge_cases.proto
3+
package com.squareup.wire.protos.kotlin.edgecases
4+
5+
import com.squareup.wire.FieldEncoding
6+
import com.squareup.wire.Message
7+
import com.squareup.wire.ProtoAdapter
8+
import com.squareup.wire.ProtoReader
9+
import com.squareup.wire.ProtoWriter
10+
import kotlin.Any
11+
import kotlin.AssertionError
12+
import kotlin.Boolean
13+
import kotlin.Deprecated
14+
import kotlin.DeprecationLevel
15+
import kotlin.Int
16+
import kotlin.Nothing
17+
import kotlin.String
18+
import kotlin.jvm.JvmField
19+
import okio.ByteString
20+
21+
class NoFields(
22+
unknownFields: ByteString = ByteString.EMPTY
23+
) : Message<NoFields, Nothing>(ADAPTER, unknownFields) {
24+
@Deprecated(
25+
message = "Shouldn't be used in Kotlin",
26+
level = DeprecationLevel.HIDDEN
27+
)
28+
override fun newBuilder(): Nothing = throw AssertionError()
29+
30+
override fun equals(other: Any?): Boolean {
31+
if (other === this) return true
32+
if (other !is NoFields) return false
33+
return unknownFields == other.unknownFields
34+
}
35+
36+
override fun hashCode(): Int = unknownFields.hashCode()
37+
38+
override fun toString(): String = "NoFields{}"
39+
40+
fun copy(unknownFields: ByteString = this.unknownFields): NoFields = NoFields(unknownFields)
41+
42+
companion object {
43+
@JvmField
44+
val ADAPTER: ProtoAdapter<NoFields> = object : ProtoAdapter<NoFields>(
45+
FieldEncoding.LENGTH_DELIMITED,
46+
NoFields::class
47+
) {
48+
override fun encodedSize(value: NoFields): Int =
49+
value.unknownFields.size
50+
51+
override fun encode(writer: ProtoWriter, value: NoFields) {
52+
writer.writeBytes(value.unknownFields)
53+
}
54+
55+
override fun decode(reader: ProtoReader): NoFields {
56+
val unknownFields = reader.forEachTag(reader::readUnknownField)
57+
return NoFields(
58+
unknownFields = unknownFields
59+
)
60+
}
61+
62+
override fun redact(value: NoFields): NoFields = value.copy(
63+
unknownFields = ByteString.EMPTY
64+
)
65+
}
66+
}
67+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Code generated by Wire protocol buffer compiler, do not edit.
2+
// Source file: edge_cases.proto
3+
package com.squareup.wire.protos.kotlin.edgecases
4+
5+
import com.squareup.wire.FieldEncoding
6+
import com.squareup.wire.Message
7+
import com.squareup.wire.ProtoAdapter
8+
import com.squareup.wire.ProtoReader
9+
import com.squareup.wire.ProtoWriter
10+
import com.squareup.wire.WireField
11+
import kotlin.Any
12+
import kotlin.AssertionError
13+
import kotlin.Boolean
14+
import kotlin.Deprecated
15+
import kotlin.DeprecationLevel
16+
import kotlin.Int
17+
import kotlin.Nothing
18+
import kotlin.String
19+
import kotlin.hashCode
20+
import kotlin.jvm.JvmField
21+
import okio.ByteString
22+
23+
class OneBytesField(
24+
@field:WireField(
25+
tag = 1,
26+
adapter = "com.squareup.wire.ProtoAdapter#BYTES"
27+
)
28+
val opt_bytes: ByteString? = null,
29+
unknownFields: ByteString = ByteString.EMPTY
30+
) : Message<OneBytesField, Nothing>(ADAPTER, unknownFields) {
31+
@Deprecated(
32+
message = "Shouldn't be used in Kotlin",
33+
level = DeprecationLevel.HIDDEN
34+
)
35+
override fun newBuilder(): Nothing = throw AssertionError()
36+
37+
override fun equals(other: Any?): Boolean {
38+
if (other === this) return true
39+
if (other !is OneBytesField) return false
40+
return unknownFields == other.unknownFields
41+
&& opt_bytes == other.opt_bytes
42+
}
43+
44+
override fun hashCode(): Int {
45+
var result = super.hashCode
46+
if (result == 0) {
47+
result = unknownFields.hashCode()
48+
result = result * 37 + opt_bytes.hashCode()
49+
super.hashCode = result
50+
}
51+
return result
52+
}
53+
54+
override fun toString(): String {
55+
val result = mutableListOf<String>()
56+
if (opt_bytes != null) result += """opt_bytes=$opt_bytes"""
57+
return result.joinToString(prefix = "OneBytesField{", separator = ", ", postfix = "}")
58+
}
59+
60+
fun copy(opt_bytes: ByteString? = this.opt_bytes, unknownFields: ByteString = this.unknownFields):
61+
OneBytesField = OneBytesField(opt_bytes, unknownFields)
62+
63+
companion object {
64+
@JvmField
65+
val ADAPTER: ProtoAdapter<OneBytesField> = object : ProtoAdapter<OneBytesField>(
66+
FieldEncoding.LENGTH_DELIMITED,
67+
OneBytesField::class
68+
) {
69+
override fun encodedSize(value: OneBytesField): Int =
70+
ProtoAdapter.BYTES.encodedSizeWithTag(1, value.opt_bytes) +
71+
value.unknownFields.size
72+
73+
override fun encode(writer: ProtoWriter, value: OneBytesField) {
74+
ProtoAdapter.BYTES.encodeWithTag(writer, 1, value.opt_bytes)
75+
writer.writeBytes(value.unknownFields)
76+
}
77+
78+
override fun decode(reader: ProtoReader): OneBytesField {
79+
var opt_bytes: ByteString? = null
80+
val unknownFields = reader.forEachTag { tag ->
81+
when (tag) {
82+
1 -> opt_bytes = ProtoAdapter.BYTES.decode(reader)
83+
else -> reader.readUnknownField(tag)
84+
}
85+
}
86+
return OneBytesField(
87+
opt_bytes = opt_bytes,
88+
unknownFields = unknownFields
89+
)
90+
}
91+
92+
override fun redact(value: OneBytesField): OneBytesField = value.copy(
93+
unknownFields = ByteString.EMPTY
94+
)
95+
}
96+
}
97+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Code generated by Wire protocol buffer compiler, do not edit.
2+
// Source file: edge_cases.proto
3+
package com.squareup.wire.protos.kotlin.edgecases
4+
5+
import com.squareup.wire.FieldEncoding
6+
import com.squareup.wire.Message
7+
import com.squareup.wire.ProtoAdapter
8+
import com.squareup.wire.ProtoReader
9+
import com.squareup.wire.ProtoWriter
10+
import com.squareup.wire.WireField
11+
import kotlin.Any
12+
import kotlin.AssertionError
13+
import kotlin.Boolean
14+
import kotlin.Deprecated
15+
import kotlin.DeprecationLevel
16+
import kotlin.Int
17+
import kotlin.Nothing
18+
import kotlin.String
19+
import kotlin.hashCode
20+
import kotlin.jvm.JvmField
21+
import okio.ByteString
22+
23+
class OneField(
24+
@field:WireField(
25+
tag = 1,
26+
adapter = "com.squareup.wire.ProtoAdapter#INT32"
27+
)
28+
val opt_int32: Int? = null,
29+
unknownFields: ByteString = ByteString.EMPTY
30+
) : Message<OneField, Nothing>(ADAPTER, unknownFields) {
31+
@Deprecated(
32+
message = "Shouldn't be used in Kotlin",
33+
level = DeprecationLevel.HIDDEN
34+
)
35+
override fun newBuilder(): Nothing = throw AssertionError()
36+
37+
override fun equals(other: Any?): Boolean {
38+
if (other === this) return true
39+
if (other !is OneField) return false
40+
return unknownFields == other.unknownFields
41+
&& opt_int32 == other.opt_int32
42+
}
43+
44+
override fun hashCode(): Int {
45+
var result = super.hashCode
46+
if (result == 0) {
47+
result = unknownFields.hashCode()
48+
result = result * 37 + opt_int32.hashCode()
49+
super.hashCode = result
50+
}
51+
return result
52+
}
53+
54+
override fun toString(): String {
55+
val result = mutableListOf<String>()
56+
if (opt_int32 != null) result += """opt_int32=$opt_int32"""
57+
return result.joinToString(prefix = "OneField{", separator = ", ", postfix = "}")
58+
}
59+
60+
fun copy(opt_int32: Int? = this.opt_int32, unknownFields: ByteString = this.unknownFields):
61+
OneField = OneField(opt_int32, unknownFields)
62+
63+
companion object {
64+
@JvmField
65+
val ADAPTER: ProtoAdapter<OneField> = object : ProtoAdapter<OneField>(
66+
FieldEncoding.LENGTH_DELIMITED,
67+
OneField::class
68+
) {
69+
override fun encodedSize(value: OneField): Int =
70+
ProtoAdapter.INT32.encodedSizeWithTag(1, value.opt_int32) +
71+
value.unknownFields.size
72+
73+
override fun encode(writer: ProtoWriter, value: OneField) {
74+
ProtoAdapter.INT32.encodeWithTag(writer, 1, value.opt_int32)
75+
writer.writeBytes(value.unknownFields)
76+
}
77+
78+
override fun decode(reader: ProtoReader): OneField {
79+
var opt_int32: Int? = null
80+
val unknownFields = reader.forEachTag { tag ->
81+
when (tag) {
82+
1 -> opt_int32 = ProtoAdapter.INT32.decode(reader)
83+
else -> reader.readUnknownField(tag)
84+
}
85+
}
86+
return OneField(
87+
opt_int32 = opt_int32,
88+
unknownFields = unknownFields
89+
)
90+
}
91+
92+
override fun redact(value: OneField): OneField = value.copy(
93+
unknownFields = ByteString.EMPTY
94+
)
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)