Java protobuf uses lower camel for all field names. When using reflection to find the generic type of repeated fields, can't use the user specified formats for field name conversion. (#1119)
This commit is contained in:
parent
558c13918e
commit
f0aa1118e9
@ -19,7 +19,6 @@ package com.google.gson.protobuf;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Converter;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
@ -94,7 +93,8 @@ public class ProtoTypeAdapter
|
||||
private final Set<Extension<FieldOptions, String>> serializedNameExtensions;
|
||||
private final Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions;
|
||||
private EnumSerialization enumSerialization;
|
||||
private Converter<String, String> fieldNameSerializationFormat;
|
||||
private CaseFormat protoFormat;
|
||||
private CaseFormat jsonFormat;
|
||||
|
||||
private Builder(EnumSerialization enumSerialization, CaseFormat fromFieldNameFormat,
|
||||
CaseFormat toFieldNameFormat) {
|
||||
@ -126,7 +126,8 @@ public class ProtoTypeAdapter
|
||||
*/
|
||||
public Builder setFieldNameSerializationFormat(CaseFormat fromFieldNameFormat,
|
||||
CaseFormat toFieldNameFormat) {
|
||||
fieldNameSerializationFormat = fromFieldNameFormat.converterTo(toFieldNameFormat);
|
||||
this.protoFormat = fromFieldNameFormat;
|
||||
this.jsonFormat = toFieldNameFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -174,7 +175,7 @@ public class ProtoTypeAdapter
|
||||
}
|
||||
|
||||
public ProtoTypeAdapter build() {
|
||||
return new ProtoTypeAdapter(enumSerialization, fieldNameSerializationFormat,
|
||||
return new ProtoTypeAdapter(enumSerialization, protoFormat, jsonFormat,
|
||||
serializedNameExtensions, serializedEnumValueExtensions);
|
||||
}
|
||||
}
|
||||
@ -195,16 +196,19 @@ public class ProtoTypeAdapter
|
||||
new MapMaker().makeMap();
|
||||
|
||||
private final EnumSerialization enumSerialization;
|
||||
private final Converter<String, String> fieldNameSerializationFormat;
|
||||
private final CaseFormat protoFormat;
|
||||
private final CaseFormat jsonFormat;
|
||||
private final Set<Extension<FieldOptions, String>> serializedNameExtensions;
|
||||
private final Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions;
|
||||
|
||||
private ProtoTypeAdapter(EnumSerialization enumSerialization,
|
||||
Converter<String, String> fieldNameSerializationFormat,
|
||||
CaseFormat protoFormat,
|
||||
CaseFormat jsonFormat,
|
||||
Set<Extension<FieldOptions, String>> serializedNameExtensions,
|
||||
Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions) {
|
||||
this.enumSerialization = enumSerialization;
|
||||
this.fieldNameSerializationFormat = fieldNameSerializationFormat;
|
||||
this.protoFormat = protoFormat;
|
||||
this.jsonFormat = jsonFormat;
|
||||
this.serializedNameExtensions = serializedNameExtensions;
|
||||
this.serializedEnumValueExtensions = serializedEnumValueExtensions;
|
||||
}
|
||||
@ -284,8 +288,9 @@ public class ProtoTypeAdapter
|
||||
protoBuilder.setField(fieldDescriptor, fieldValue);
|
||||
} else if (fieldDescriptor.isRepeated()) {
|
||||
// If the type is an array, then we have to grab the type from the class.
|
||||
// protobuf java field names are always lower camel case
|
||||
String protoArrayFieldName =
|
||||
fieldNameSerializationFormat.convert(fieldDescriptor.getName()) + "_";
|
||||
protoFormat.to(CaseFormat.LOWER_CAMEL, fieldDescriptor.getName()) + "_";
|
||||
Field protoArrayField = protoClass.getDeclaredField(protoArrayFieldName);
|
||||
Type protoArrayFieldType = protoArrayField.getGenericType();
|
||||
fieldValue = context.deserialize(jsonElement, protoArrayFieldType);
|
||||
@ -325,7 +330,7 @@ public class ProtoTypeAdapter
|
||||
return options.getExtension(extension);
|
||||
}
|
||||
}
|
||||
return fieldNameSerializationFormat.convert(defaultName);
|
||||
return protoFormat.to(jsonFormat, defaultName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,6 +24,11 @@ message SimpleProto {
|
||||
optional int32 count = 2;
|
||||
}
|
||||
|
||||
message ProtoWithDifferentCaseFormat {
|
||||
repeated string name_that_tests_case_format = 1;
|
||||
optional string another_field = 2;
|
||||
}
|
||||
|
||||
message ProtoWithRepeatedFields {
|
||||
repeated int64 numbers = 1;
|
||||
repeated SimpleProto simples = 2;
|
||||
|
@ -15,10 +15,13 @@
|
||||
*/
|
||||
package com.google.gson.protobuf.functional;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.protobuf.ProtoTypeAdapter;
|
||||
import com.google.gson.protobuf.ProtoTypeAdapter.EnumSerialization;
|
||||
import com.google.gson.protobuf.generated.Bag.ProtoWithDifferentCaseFormat;
|
||||
import com.google.gson.protobuf.generated.Bag.ProtoWithRepeatedFields;
|
||||
import com.google.gson.protobuf.generated.Bag.SimpleProto;
|
||||
import com.google.protobuf.GeneratedMessage;
|
||||
@ -32,6 +35,7 @@ import junit.framework.TestCase;
|
||||
*/
|
||||
public class ProtosWithComplexAndRepeatedFieldsTest extends TestCase {
|
||||
private Gson gson;
|
||||
private Gson upperCamelGson;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
@ -43,6 +47,14 @@ public class ProtosWithComplexAndRepeatedFieldsTest extends TestCase {
|
||||
.setEnumSerialization(EnumSerialization.NUMBER)
|
||||
.build())
|
||||
.create();
|
||||
upperCamelGson =
|
||||
new GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(
|
||||
GeneratedMessage.class, ProtoTypeAdapter.newBuilder()
|
||||
.setFieldNameSerializationFormat(
|
||||
CaseFormat.LOWER_UNDERSCORE, CaseFormat.UPPER_CAMEL)
|
||||
.build())
|
||||
.create();
|
||||
}
|
||||
|
||||
public void testSerializeRepeatedFields() {
|
||||
@ -67,4 +79,23 @@ public class ProtosWithComplexAndRepeatedFieldsTest extends TestCase {
|
||||
assertEquals("bar", proto.getSimples(0).getMsg());
|
||||
assertEquals(7, proto.getSimples(1).getCount());
|
||||
}
|
||||
|
||||
public void testSerializeDifferentCaseFormat() {
|
||||
final ProtoWithDifferentCaseFormat proto =
|
||||
ProtoWithDifferentCaseFormat.newBuilder()
|
||||
.setAnotherField("foo")
|
||||
.addNameThatTestsCaseFormat("bar")
|
||||
.build();
|
||||
final JsonObject json = upperCamelGson.toJsonTree(proto).getAsJsonObject();
|
||||
assertEquals("foo", json.get("AnotherField").getAsString());
|
||||
assertEquals("bar", json.get("NameThatTestsCaseFormat").getAsJsonArray().get(0).getAsString());
|
||||
}
|
||||
|
||||
public void testDeserializeDifferentCaseFormat() {
|
||||
final String json = "{NameThatTestsCaseFormat:['bar'],AnotherField:'foo'}";
|
||||
ProtoWithDifferentCaseFormat proto =
|
||||
upperCamelGson.fromJson(json, ProtoWithDifferentCaseFormat.class);
|
||||
assertEquals("foo", proto.getAnotherField());
|
||||
assertEquals("bar", proto.getNameThatTestsCaseFormat(0));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user