mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-20 11:08:31 +00:00
Merge various proto utils together in core-util-jvm.
This commit is contained in:
@@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.backup.v2.database
|
|||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import androidx.core.content.contentValuesOf
|
import androidx.core.content.contentValuesOf
|
||||||
import org.signal.core.util.SqlUtil
|
import org.signal.core.util.SqlUtil
|
||||||
|
import org.signal.core.util.decodeOrNull
|
||||||
import org.signal.core.util.insertInto
|
import org.signal.core.util.insertInto
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.requireBlob
|
import org.signal.core.util.requireBlob
|
||||||
@@ -30,7 +31,6 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.ChatColor
|
|||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper
|
import org.thoughtcrime.securesms.database.model.databaseprotos.Wallpaper
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.util.decodeOrNull
|
|
||||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory
|
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperFactory
|
||||||
import org.thoughtcrime.securesms.wallpaper.UriChatWallpaper
|
import org.thoughtcrime.securesms.wallpaper.UriChatWallpaper
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
package org.thoughtcrime.securesms.database.model
|
package org.thoughtcrime.securesms.database.model
|
||||||
|
|
||||||
import ProtoUtil.isNullOrEmpty
|
|
||||||
import okio.ByteString
|
import okio.ByteString
|
||||||
import org.signal.core.util.StringUtil
|
import org.signal.core.util.StringUtil
|
||||||
|
import org.signal.core.util.isNullOrEmpty
|
||||||
import org.signal.storageservice.protos.groups.AccessControl
|
import org.signal.storageservice.protos.groups.AccessControl
|
||||||
import org.signal.storageservice.protos.groups.AccessControl.AccessRequired
|
import org.signal.storageservice.protos.groups.AccessControl.AccessRequired
|
||||||
import org.signal.storageservice.protos.groups.Member
|
import org.signal.storageservice.protos.groups.Member
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.thoughtcrime.securesms.messages
|
package org.thoughtcrime.securesms.messages
|
||||||
|
|
||||||
import ProtoUtil.isNotEmpty
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import com.mobilecoin.lib.exceptions.SerializationException
|
import com.mobilecoin.lib.exceptions.SerializationException
|
||||||
@@ -8,6 +7,7 @@ import okio.ByteString.Companion.toByteString
|
|||||||
import org.signal.core.util.Base64
|
import org.signal.core.util.Base64
|
||||||
import org.signal.core.util.Hex
|
import org.signal.core.util.Hex
|
||||||
import org.signal.core.util.concurrent.SignalExecutors
|
import org.signal.core.util.concurrent.SignalExecutors
|
||||||
|
import org.signal.core.util.isNotEmpty
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.signal.core.util.orNull
|
import org.signal.core.util.orNull
|
||||||
import org.signal.core.util.toOptional
|
import org.signal.core.util.toOptional
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.thoughtcrime.securesms.messages
|
package org.thoughtcrime.securesms.messages
|
||||||
|
|
||||||
import ProtoUtil.isNotEmpty
|
|
||||||
import com.squareup.wire.Message
|
import com.squareup.wire.Message
|
||||||
import okio.ByteString
|
import okio.ByteString
|
||||||
import okio.ByteString.Companion.toByteString
|
import okio.ByteString.Companion.toByteString
|
||||||
|
import org.signal.core.util.isNotEmpty
|
||||||
import org.signal.core.util.orNull
|
import org.signal.core.util.orNull
|
||||||
import org.signal.libsignal.protocol.message.DecryptionErrorMessage
|
import org.signal.libsignal.protocol.message.DecryptionErrorMessage
|
||||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
|
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.thoughtcrime.securesms.messages
|
package org.thoughtcrime.securesms.messages
|
||||||
|
|
||||||
import ProtoUtil.isNotEmpty
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.mobilecoin.lib.exceptions.SerializationException
|
import com.mobilecoin.lib.exceptions.SerializationException
|
||||||
import okio.ByteString
|
import okio.ByteString
|
||||||
import org.signal.core.util.Base64
|
import org.signal.core.util.Base64
|
||||||
import org.signal.core.util.Hex
|
import org.signal.core.util.Hex
|
||||||
|
import org.signal.core.util.isNotEmpty
|
||||||
import org.signal.core.util.orNull
|
import org.signal.core.util.orNull
|
||||||
import org.signal.libsignal.protocol.IdentityKey
|
import org.signal.libsignal.protocol.IdentityKey
|
||||||
import org.signal.libsignal.protocol.InvalidKeyException
|
import org.signal.libsignal.protocol.InvalidKeyException
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.thoughtcrime.securesms.util
|
|
||||||
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException
|
|
||||||
import com.squareup.wire.ProtoAdapter
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs the common pattern of attempting to decode a serialized proto and returning null if it fails to decode.
|
|
||||||
*/
|
|
||||||
fun <E> ProtoAdapter<E>.decodeOrNull(serialized: ByteArray): E? {
|
|
||||||
return try {
|
|
||||||
this.decode(serialized)
|
|
||||||
} catch (e: InvalidProtocolBufferException) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,7 @@ plugins {
|
|||||||
id("java-library")
|
id("java-library")
|
||||||
id("org.jetbrains.kotlin.jvm")
|
id("org.jetbrains.kotlin.jvm")
|
||||||
id("ktlint")
|
id("ktlint")
|
||||||
|
id("com.squareup.wire")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
@@ -23,6 +24,16 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wire {
|
||||||
|
kotlin {
|
||||||
|
javaInterop = true
|
||||||
|
}
|
||||||
|
|
||||||
|
sourcePath {
|
||||||
|
srcDir("src/main/protowire")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.kotlin.reflect)
|
implementation(libs.kotlin.reflect)
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:JvmName("ProtoUtil")
|
||||||
|
|
||||||
|
package org.signal.core.util
|
||||||
|
|
||||||
|
import com.squareup.wire.FieldEncoding
|
||||||
|
import com.squareup.wire.Message
|
||||||
|
import com.squareup.wire.ProtoAdapter
|
||||||
|
import com.squareup.wire.ProtoReader
|
||||||
|
import com.squareup.wire.ProtoWriter
|
||||||
|
import okio.Buffer
|
||||||
|
import okio.ByteString
|
||||||
|
import org.signal.core.util.logging.Log
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.LinkedList
|
||||||
|
|
||||||
|
private const val TAG = "ProtoExtension"
|
||||||
|
|
||||||
|
fun ByteString?.isNotEmpty(): Boolean {
|
||||||
|
return this != null && this.size > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ByteString?.isNullOrEmpty(): Boolean {
|
||||||
|
return this == null || this.size == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the common pattern of attempting to decode a serialized proto and returning null if it fails to decode.
|
||||||
|
*/
|
||||||
|
fun <E> ProtoAdapter<E>.decodeOrNull(serialized: ByteArray): E? {
|
||||||
|
return try {
|
||||||
|
this.decode(serialized)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if there are unknown fields anywhere inside the proto or its nested protos.
|
||||||
|
*/
|
||||||
|
fun Message<*, *>.hasUnknownFields(): Boolean {
|
||||||
|
val allProtos = this.getInnerProtos()
|
||||||
|
allProtos.add(this)
|
||||||
|
for (proto in allProtos) {
|
||||||
|
val unknownFields = proto.unknownFields
|
||||||
|
if (unknownFields.size > 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Message<*, *>.getUnknownEnumValue(tag: Int): Int {
|
||||||
|
val reader = ProtoReader(Buffer().write(this.unknownFields))
|
||||||
|
reader.forEachTag { unknownTag ->
|
||||||
|
if (unknownTag == tag) {
|
||||||
|
return ProtoAdapter.INT32.decode(reader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw AssertionError("Tag $tag not found in unknown fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun writeUnknownEnumValue(tag: Int, enumValue: Int): ByteString {
|
||||||
|
val buffer = Buffer()
|
||||||
|
val writer = ProtoWriter(buffer)
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(FieldEncoding.VARINT.rawProtoAdapter() as ProtoAdapter<Any>).encodeWithTag(writer, tag, enumValue.toLong())
|
||||||
|
|
||||||
|
return buffer.readByteString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively retrieves all inner complex proto types inside a given proto.
|
||||||
|
*/
|
||||||
|
private fun Message<*, *>.getInnerProtos(): MutableList<Message<*, *>> {
|
||||||
|
val innerProtos: MutableList<Message<*, *>> = LinkedList()
|
||||||
|
try {
|
||||||
|
val fields = this.javaClass.declaredFields
|
||||||
|
for (field in fields) {
|
||||||
|
if (Message::class.java.isAssignableFrom(field.type)) {
|
||||||
|
field.isAccessible = true
|
||||||
|
val inner = field[this] as? Message<*, *>
|
||||||
|
if (inner != null) {
|
||||||
|
innerProtos.add(inner)
|
||||||
|
innerProtos.addAll(inner.getInnerProtos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IllegalAccessException) {
|
||||||
|
Log.w(TAG, "Failed to get inner protos!", e)
|
||||||
|
}
|
||||||
|
return innerProtos
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:JvmName("ProtoUtil")
|
|
||||||
|
|
||||||
import okio.ByteString
|
|
||||||
|
|
||||||
object ProtoUtil {
|
|
||||||
|
|
||||||
fun ByteString?.isNotEmpty(): Boolean {
|
|
||||||
return this != null && this.size > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ByteString?.isNullOrEmpty(): Boolean {
|
|
||||||
return this == null || this.size == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.whispersystems.signalservice.api.payments.PaymentsConstants;
|
import org.whispersystems.signalservice.api.payments.PaymentsConstants;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
|
import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.OptionalBool;
|
import org.whispersystems.signalservice.internal.storage.protos.OptionalBool;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
|
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
|
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
|
||||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord;
|
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.GroupV1Record;
|
import org.whispersystems.signalservice.internal.storage.protos.GroupV1Record;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
|
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
import org.whispersystems.signalservice.api.messages.multidevice.MessageRequestResponseMessage;
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
|
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.StorageManifest;
|
import org.whispersystems.signalservice.internal.storage.protos.StorageManifest;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.InvalidKeyException;
|
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
|
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.StorageItem;
|
import org.whispersystems.signalservice.internal.storage.protos.StorageItem;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.StorageManifest;
|
import org.whispersystems.signalservice.internal.storage.protos.StorageManifest;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.whispersystems.signalservice.api.storage;
|
package org.whispersystems.signalservice.api.storage;
|
||||||
|
|
||||||
|
import org.signal.core.util.ProtoUtil;
|
||||||
import org.signal.libsignal.protocol.logging.Log;
|
import org.signal.libsignal.protocol.logging.Log;
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.StoryDistributionListRecord;
|
import org.whispersystems.signalservice.internal.storage.protos.StoryDistributionListRecord;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:JvmName("ProtoUtil")
|
|
||||||
|
|
||||||
package org.whispersystems.signalservice.api.util
|
|
||||||
|
|
||||||
import com.squareup.wire.FieldEncoding
|
|
||||||
import com.squareup.wire.Message
|
|
||||||
import com.squareup.wire.ProtoAdapter
|
|
||||||
import com.squareup.wire.ProtoReader
|
|
||||||
import com.squareup.wire.ProtoWriter
|
|
||||||
import okio.Buffer
|
|
||||||
import okio.ByteString
|
|
||||||
import org.signal.libsignal.protocol.logging.Log
|
|
||||||
import java.util.LinkedList
|
|
||||||
|
|
||||||
object ProtoUtil {
|
|
||||||
private val TAG = ProtoUtil::class.java.simpleName
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if there are unknown fields anywhere inside the proto or its nested protos.
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
fun hasUnknownFields(rootProto: Message<*, *>): Boolean {
|
|
||||||
val allProtos = getInnerProtos(rootProto)
|
|
||||||
allProtos.add(rootProto)
|
|
||||||
for (proto in allProtos) {
|
|
||||||
val unknownFields = proto.unknownFields
|
|
||||||
if (unknownFields.size > 0) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getUnknownEnumValue(proto: Message<*, *>, tag: Int): Int {
|
|
||||||
val reader = ProtoReader(Buffer().write(proto.unknownFields))
|
|
||||||
reader.forEachTag { unknownTag ->
|
|
||||||
if (unknownTag == tag) {
|
|
||||||
return ProtoAdapter.INT32.decode(reader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw AssertionError("Tag $tag not found in unknown fields")
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun writeUnknownEnumValue(tag: Int, enumValue: Int): ByteString {
|
|
||||||
val buffer = Buffer()
|
|
||||||
val writer = ProtoWriter(buffer)
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
(FieldEncoding.VARINT.rawProtoAdapter() as ProtoAdapter<Any>).encodeWithTag(writer, tag, enumValue.toLong())
|
|
||||||
|
|
||||||
return buffer.readByteString()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively retrieves all inner complex proto types inside a given proto.
|
|
||||||
*/
|
|
||||||
private fun getInnerProtos(proto: Message<*, *>): MutableList<Message<*, *>> {
|
|
||||||
val innerProtos: MutableList<Message<*, *>> = LinkedList()
|
|
||||||
try {
|
|
||||||
val fields = proto.javaClass.declaredFields
|
|
||||||
for (field in fields) {
|
|
||||||
if (Message::class.java.isAssignableFrom(field.type)) {
|
|
||||||
field.isAccessible = true
|
|
||||||
val inner = field[proto] as? Message<*, *>
|
|
||||||
if (inner != null) {
|
|
||||||
innerProtos.add(inner)
|
|
||||||
innerProtos.addAll(getInnerProtos(inner))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: IllegalAccessException) {
|
|
||||||
Log.w(TAG, "Failed to get inner protos!", e)
|
|
||||||
}
|
|
||||||
return innerProtos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user