Skip to content
Draft
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 @@ -43,6 +43,13 @@ class AnyMessageTypeAdapter(
val protoAdapter = typeUrlToAdapter[value.typeUrl]
?: throw IOException("Cannot find type for url: ${value.typeUrl}")

if (protoAdapter == ProtoAdapter.FIELD_MASK) {
writer.name("value")
gson.getAdapter(FieldMask::class.java).write(writer, value.unpack(ProtoAdapter.FIELD_MASK))
writer.endObject()
return
}

@Suppress("UNCHECKED_CAST")
val delegate = gson.getAdapter(protoAdapter.type!!.java) as TypeAdapter<Message<*, *>>

Expand All @@ -69,6 +76,13 @@ class AnyMessageTypeAdapter(
val protoAdapter = typeUrlToAdapter[typeUrl]
?: throw IOException("Cannot resolve type: $typeUrl in ${reader.path}")

if (protoAdapter == ProtoAdapter.FIELD_MASK) {
val fieldMask = jsonElement.asJsonObject.get("value")?.let {
gson.getAdapter(FieldMask::class.java).fromJsonTree(it)
} ?: FieldMask()
return AnyMessage(typeUrl, ProtoAdapter.FIELD_MASK.encodeByteString(fieldMask))
}

@Suppress("UNCHECKED_CAST")
val delegate = gson.getAdapter(protoAdapter.type!!.java) as TypeAdapter<Message<*, *>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.google.gson.TypeAdapter
import com.google.gson.TypeAdapterFactory
import com.google.gson.reflect.TypeToken
import com.squareup.wire.internal.EnumJsonFormatter
import com.squareup.wire.internal.FieldMaskJsonFormatter
import com.squareup.wire.internal.createRuntimeMessageAdapter

/**
Expand Down Expand Up @@ -82,6 +83,7 @@ class WireTypeAdapterFactory @JvmOverloads constructor(

return when {
rawType == AnyMessage::class.java -> AnyMessageTypeAdapter(gson, typeUrlToAdapter) as TypeAdapter<T>
rawType == FieldMask::class.java -> GsonJsonIntegration.formatterAdapter(FieldMaskJsonFormatter) as TypeAdapter<T>
Message::class.java.isAssignableFrom(rawType) -> {
val messageAdapter = createRuntimeMessageAdapter<Nothing, Nothing>(
messageType = rawType as Class<Nothing>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ internal class AnyMessageJsonAdapter(
val protoAdapter = typeUrlToAdapter[value.typeUrl]
?: throw JsonDataException("Cannot find type for url: ${value.typeUrl} in ${writer.path}")

if (protoAdapter == ProtoAdapter.FIELD_MASK) {
@Suppress("UNCHECKED_CAST")
val delegate = moshi.adapter(FieldMask::class.java) as JsonAdapter<FieldMask>
writer.name("value")
delegate.toJson(writer, value.unpack(ProtoAdapter.FIELD_MASK))
writer.endObject()
return
}

@Suppress("UNCHECKED_CAST")
val delegate = moshi.adapter(protoAdapter.type!!.java) as JsonAdapter<Message<*, *>>

Expand All @@ -63,6 +72,24 @@ internal class AnyMessageJsonAdapter(
val protoAdapter = typeUrlToAdapter[typeUrl]
?: throw JsonDataException("Cannot resolve type: $typeUrl in ${reader.path}")

if (protoAdapter == ProtoAdapter.FIELD_MASK) {
@Suppress("UNCHECKED_CAST")
val delegate = moshi.adapter(FieldMask::class.java) as JsonAdapter<FieldMask>
var fieldMask = FieldMask()

reader.beginObject()
while (reader.hasNext()) {
when (reader.nextName()) {
"@type" -> reader.skipValue()
"value" -> fieldMask = delegate.fromJson(reader) ?: FieldMask()
else -> reader.skipValue()
}
}
reader.endObject()

return AnyMessage(typeUrl, ProtoAdapter.FIELD_MASK.encodeByteString(fieldMask))
}

@Suppress("UNCHECKED_CAST")
val delegate = moshi.adapter(protoAdapter.type!!.java) as JsonAdapter<Message<*, *>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.wire.internal.EnumJsonFormatter
import com.squareup.wire.internal.FieldMaskJsonFormatter
import com.squareup.wire.internal.createRuntimeMessageAdapter
import java.lang.reflect.Type

Expand Down Expand Up @@ -83,6 +84,7 @@ class WireJsonAdapterFactory @JvmOverloads constructor(
return when {
annotations.isNotEmpty() -> null
rawType == AnyMessage::class.java -> AnyMessageJsonAdapter(moshi, typeUrlToAdapter)
rawType == FieldMask::class.java -> MoshiJsonIntegration.formatterAdapter(FieldMaskJsonFormatter)
Message::class.java.isAssignableFrom(rawType) -> {
val messageAdapter = createRuntimeMessageAdapter<Nothing, Nothing>(
messageType = type as Class<Nothing>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ syntax = "proto3";
package squareup.proto3;

import "google/protobuf/field_mask.proto";
import "google/protobuf/any.proto";

message ContainsFieldMask {
google.protobuf.FieldMask mask = 1;
repeated google.protobuf.FieldMask masks = 2;
google.protobuf.Any any_mask = 3;
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class WireJsonTest {
}

@Test fun fieldMask() {
val anyFieldMask = FieldMask(listOf("masked_name"))
val value = ContainsFieldMask.Builder()
.mask(FieldMask(listOf("user.display_name", "photo", "foo_bar.baz_qux")))
.masks(
Expand All @@ -277,11 +278,22 @@ class WireJsonTest {
FieldMask(listOf("updated_at.seconds")),
),
)
.any_mask(
AnyMessage(
ProtoAdapter.FIELD_MASK.typeUrl!!,
ProtoAdapter.FIELD_MASK.encodeByteString(anyFieldMask),
),
)
.build()
val anyFieldName = if (jsonLibrary.preservingProtoFieldNames) "any_mask" else "anyMask"
val json = """
|{
| "mask": "user.displayName,photo,fooBar.bazQux",
| "masks": ["displayName", "updatedAt.seconds"]
| "masks": ["displayName", "updatedAt.seconds"],
| "$anyFieldName": {
| "@type": "type.googleapis.com/google.protobuf.FieldMask",
| "value": "maskedName"
| }
|}
""".trimMargin()

Expand All @@ -295,6 +307,14 @@ class WireJsonTest {
)
}

@Test fun rootFieldMask() {
val value = FieldMask(listOf("user.display_name", "photo", "foo_bar.baz_qux"))
val json = "\"user.displayName,photo,fooBar.bazQux\""

assertThat(jsonLibrary.toJson(value, FieldMask::class.java)).isEqualTo(json)
assertThat(jsonLibrary.fromJson(json, FieldMask::class.java)).isEqualTo(value)
}

@Test fun anyMessageWithUnregisteredTypeOnReading() {
try {
jsonLibrary.fromJson(PIZZA_DELIVERY_UNKNOWN_TYPE_JSON, PizzaDelivery::class.java)
Expand Down Expand Up @@ -1223,7 +1243,7 @@ class WireJsonTest {
private val moshi = Moshi.Builder()
.add(
WireJsonAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.build()

Expand All @@ -1245,7 +1265,7 @@ class WireJsonTest {
private val gson = GsonBuilder()
.registerTypeAdapterFactory(
WireTypeAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.disableHtmlEscaping()
.create()
Expand All @@ -1268,7 +1288,7 @@ class WireJsonTest {
private val moshi = Moshi.Builder()
.add(
WireJsonAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.build()

Expand All @@ -1290,7 +1310,7 @@ class WireJsonTest {
private val gson = GsonBuilder()
.registerTypeAdapterFactory(
WireTypeAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.disableHtmlEscaping()
.create()
Expand All @@ -1313,7 +1333,7 @@ class WireJsonTest {
private val moshi = Moshi.Builder()
.add(
WireJsonAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.build()

Expand All @@ -1335,7 +1355,7 @@ class WireJsonTest {
private val gson = GsonBuilder()
.registerTypeAdapterFactory(
WireTypeAdapterFactory(writeIdentityValues = writeIdentityValues, preservingProtoFieldNames = preservingProtoFieldNames)
.plus(listOf(BuyOneGetOnePromotion.ADAPTER)),
.plus(listOf(BuyOneGetOnePromotion.ADAPTER, ProtoAdapter.FIELD_MASK)),
)
.disableHtmlEscaping()
.create()
Expand Down
Loading