From cae0d97f16a96ce904fa4935dfc53ca712e36f5c Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Mon, 10 Jun 2024 23:33:53 -0700 Subject: [PATCH 1/7] Change the parameters for the `getCustSerializedName(FieldDescriptor)` method In the other commits in this PR, I plan to introduce branching logic inside of the customization of the serialized name for fields. This change is a pure refactor that serves to isolate the business logic into a separate commit so as to make it easier to understand. --- .../com/google/gson/protobuf/ProtoTypeAdapter.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java index 7b872f1885..d44d6db761 100644 --- a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java +++ b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java @@ -224,7 +224,7 @@ public JsonElement serialize(Message src, Type typeOfSrc, JsonSerializationConte for (Map.Entry<FieldDescriptor, Object> fieldPair : fields.entrySet()) { final FieldDescriptor desc = fieldPair.getKey(); - String name = getCustSerializedName(desc.getOptions(), desc.getName()); + String name = getCustSerializedName(desc); if (desc.getType() == ENUM_TYPE) { // Enum collections are also returned as ENUM_TYPE @@ -272,8 +272,7 @@ public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationCo (Descriptor) getCachedMethod(protoClass, "getDescriptor").invoke(null); // Call setters on all of the available fields for (FieldDescriptor fieldDescriptor : protoDescriptor.getFields()) { - String jsonFieldName = - getCustSerializedName(fieldDescriptor.getOptions(), fieldDescriptor.getName()); + String jsonFieldName = getCustSerializedName(fieldDescriptor); JsonElement jsonElement = jsonObject.get(jsonFieldName); if (jsonElement != null && !jsonElement.isJsonNull()) { @@ -317,16 +316,17 @@ public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationCo } /** - * Retrieves the custom field name from the given options, and if not found, returns the specified - * default name. + * Retrieves the custom field name for a given FieldDescriptor via its field options, falling back + * to its name as a default. */ - private String getCustSerializedName(FieldOptions options, String defaultName) { + private String getCustSerializedName(FieldDescriptor fieldDescriptor) { + FieldOptions options = fieldDescriptor.getOptions(); for (Extension<FieldOptions, String> extension : serializedNameExtensions) { if (options.hasExtension(extension)) { return options.getExtension(extension); } } - return protoFormat.to(jsonFormat, defaultName); + return protoFormat.to(jsonFormat, fieldDescriptor.getName()); } /** From 4907723bc246c50137685ebb2ce26bebd38d0ce0 Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Mon, 10 Jun 2024 23:52:27 -0700 Subject: [PATCH 2/7] Allow reading `json_name` field option for proto serialization --- .../gson/protobuf/ProtoTypeAdapter.java | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java index d44d6db761..5bc8110e13 100644 --- a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java +++ b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java @@ -89,6 +89,7 @@ public static class Builder { private EnumSerialization enumSerialization; private CaseFormat protoFormat; private CaseFormat jsonFormat; + private boolean shouldUseJsonNameFieldOption; private Builder( EnumSerialization enumSerialization, @@ -98,6 +99,7 @@ private Builder( this.serializedEnumValueExtensions = new HashSet<>(); setEnumSerialization(enumSerialization); setFieldNameSerializationFormat(fromFieldNameFormat, toFieldNameFormat); + this.shouldUseJsonNameFieldOption = false; } @CanIgnoreReturnValue @@ -174,13 +176,37 @@ public Builder addSerializedEnumValueExtension( return this; } + /** + * Sets or unsets a flag that, when set, causes the adapter to use the `json_name` field option + * from a proto field for serialization. This `json_name` option is an annotation applied to + * proto fields that cannot be read from the descriptor's options + * (`FieldDescriptor::getOptions`) as it is only available via `FieldDescriptor::getJsonName`. + * + * <p>This flag is subordinate to any custom serialized name extensions added to this adapter. + * In other words, serialized name extensions take precedence over this setting. For example, a + * field defined like: + * + * <pre> + * string client_app_id = 1 [json_name = "foo", (serialized_name) = "bar"]; + * </pre> + * + * ...will be serialized as '{@code bar}' if `shouldUseJsonNameFieldOption` is set to `true` and + * the '{@code serialized_name}' annotation is added to the adapter. + */ + @CanIgnoreReturnValue + public Builder setShouldUseJsonNameFieldOption(boolean shouldUseJsonNameFieldOption) { + this.shouldUseJsonNameFieldOption = shouldUseJsonNameFieldOption; + return this; + } + public ProtoTypeAdapter build() { return new ProtoTypeAdapter( enumSerialization, protoFormat, jsonFormat, serializedNameExtensions, - serializedEnumValueExtensions); + serializedEnumValueExtensions, + shouldUseJsonNameFieldOption); } } @@ -203,18 +229,21 @@ public static Builder newBuilder() { private final CaseFormat jsonFormat; private final Set<Extension<FieldOptions, String>> serializedNameExtensions; private final Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions; + private final boolean shouldUseJsonNameFieldOption; private ProtoTypeAdapter( EnumSerialization enumSerialization, CaseFormat protoFormat, CaseFormat jsonFormat, Set<Extension<FieldOptions, String>> serializedNameExtensions, - Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions) { + Set<Extension<EnumValueOptions, String>> serializedEnumValueExtensions, + boolean shouldUseJsonNameFieldOption) { this.enumSerialization = enumSerialization; this.protoFormat = protoFormat; this.jsonFormat = jsonFormat; this.serializedNameExtensions = serializedNameExtensions; this.serializedEnumValueExtensions = serializedEnumValueExtensions; + this.shouldUseJsonNameFieldOption = shouldUseJsonNameFieldOption; } @Override @@ -326,6 +355,9 @@ private String getCustSerializedName(FieldDescriptor fieldDescriptor) { return options.getExtension(extension); } } + if (fieldDescriptor.toProto().hasJsonName() && shouldUseJsonNameFieldOption) { + return fieldDescriptor.getJsonName(); + } return protoFormat.to(jsonFormat, fieldDescriptor.getName()); } From 5c555a6d41b66ec9f1f4791fd1306dc57f4ed38c Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Mon, 10 Jun 2024 23:59:26 -0700 Subject: [PATCH 3/7] Add tests for reading `json_name` field option --- ...ProtosWithAnnotationsAndJsonNamesTest.java | 206 ++++++++++++++++++ proto/src/test/proto/bag.proto | 9 +- 2 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java diff --git a/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java new file mode 100644 index 0000000000..6b181fa41d --- /dev/null +++ b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.protobuf.functional; + +import static com.google.common.truth.Truth.assertThat; +// import static org.junit.Assert.assertThrows; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +// import com.google.gson.JsonParseException; +import com.google.gson.protobuf.ProtoTypeAdapter; +import com.google.gson.protobuf.generated.Annotations; +import com.google.gson.protobuf.generated.Bag.ProtoWithAnnotationsAndJsonNames; +import com.google.protobuf.GeneratedMessage; +import java.util.Map; +import org.junit.Test; + +/** + * Functional tests for protocol buffers using annotations and custom json_name values for field + * names. + * + * @author Andrew Szeto + */ +public class ProtosWithAnnotationsAndJsonNamesTest { + private static final Gson GSON_PLAIN = + new GsonBuilder() + .registerTypeHierarchyAdapter( + GeneratedMessage.class, ProtoTypeAdapter.newBuilder().build()) + .create(); + private static final Gson GSON_WITH_SERIALIZED_NAME = + new GsonBuilder() + .registerTypeHierarchyAdapter( + GeneratedMessage.class, + ProtoTypeAdapter.newBuilder() + .addSerializedNameExtension(Annotations.serializedName) + .setShouldUseJsonNameFieldOption(false) + .build()) + .create(); + private static final Gson GSON_WITH_JSON_NAME = + new GsonBuilder() + .registerTypeHierarchyAdapter( + GeneratedMessage.class, + ProtoTypeAdapter.newBuilder().setShouldUseJsonNameFieldOption(true).build()) + .create(); + private static final Gson GSON_WITH_SERIALIZED_NAME_AND_JSON_NAME = + new GsonBuilder() + .registerTypeHierarchyAdapter( + GeneratedMessage.class, + ProtoTypeAdapter.newBuilder() + .addSerializedNameExtension(Annotations.serializedName) + .setShouldUseJsonNameFieldOption(true) + .build()) + .create(); + + private static final Map<Gson, String> JSON_OUTPUTS = + Map.of( + GSON_PLAIN, + "{\"neither\":\"xxx\",\"jsonNameOnly\":\"yyy\",\"annotationOnly\":\"zzz\",\"both\":\"www\"}", + GSON_WITH_JSON_NAME, + "{\"neither\":\"xxx\",\"aaa\":\"yyy\",\"annotationOnly\":\"zzz\",\"ccc\":\"www\"}", + GSON_WITH_SERIALIZED_NAME, + "{\"neither\":\"xxx\",\"jsonNameOnly\":\"yyy\",\"bbb\":\"zzz\",\"ddd\":\"www\"}", + GSON_WITH_SERIALIZED_NAME_AND_JSON_NAME, + "{\"neither\":\"xxx\",\"aaa\":\"yyy\",\"bbb\":\"zzz\",\"ddd\":\"www\"}"); + + private static final ProtoWithAnnotationsAndJsonNames PROTO = + ProtoWithAnnotationsAndJsonNames.newBuilder() + .setNeither("xxx") + .setJsonNameOnly("yyy") + .setAnnotationOnly("zzz") + .setBoth("www") + .build(); + + @Test + public void testProtoWithAnnotationsAndJsonNames_basicConversions() { + JSON_OUTPUTS.forEach( + (gson, json) -> { + assertThat(gson.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)).isEqualTo(PROTO); + assertThat(gson.toJson(PROTO)).isEqualTo(json); + }); + } + + @Test + public void testProtoWithAnnotationsAndJsonNames_basicRoundTrips() { + JSON_OUTPUTS.forEach( + (gson, json) -> { + assertThat(roundTrip(gson, gson, json)).isEqualTo(json); + assertThat(roundTrip(gson, gson, PROTO)).isEqualTo(PROTO); + }); + } + + @Test + public void testProtoWithAnnotationsAndJsonNames_unannotatedField() { + ProtoWithAnnotationsAndJsonNames proto = + ProtoWithAnnotationsAndJsonNames.newBuilder().setNeither("zzz").build(); + String json = "{\"neither\":\"zzz\"}"; + + for (Gson gson1 : JSON_OUTPUTS.keySet()) { + for (Gson gson2 : JSON_OUTPUTS.keySet()) { + // all configs should match with each other in how they serialize this proto, and they + // should be able to deserialize any other config's serialization of the proto back to its + // original form + assertThat(gson1.toJson(proto)).isEqualTo(gson2.toJson(proto)); + assertThat(roundTrip(gson1, gson2, proto)).isEqualTo(proto); + assertThat(roundTrip(gson2, gson1, proto)).isEqualTo(proto); + // the same, but in the other direction + assertThat(gson1.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)) + .isEqualTo(gson2.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)); + assertThat(roundTrip(gson1, gson2, json)).isEqualTo(json); + assertThat(roundTrip(gson2, gson1, json)).isEqualTo(json); + } + } + } + + @Test + public void testProtoWithAnnotationsAndJsonNames_fieldWithJsonName() { + ProtoWithAnnotationsAndJsonNames proto = + ProtoWithAnnotationsAndJsonNames.newBuilder().setJsonNameOnly("zzz").build(); + String jsonWithoutJsonName = "{\"jsonNameOnly\":\"zzz\"}"; + String jsonWithJsonName = "{\"aaa\":\"zzz\"}"; + + // the ProtoTypeAdapter that checks for the custom annotation should default to the basic name + assertThat(GSON_PLAIN.toJson(proto)).isEqualTo(jsonWithoutJsonName); + assertThat(GSON_WITH_SERIALIZED_NAME.toJson(proto)).isEqualTo(GSON_PLAIN.toJson(proto)); + + // the ProtoTypeAdapter that respects the `json_name` option should not have the same output as + // the base case + assertThat(GSON_WITH_JSON_NAME.toJson(proto)).isNotEqualTo(GSON_PLAIN.toJson(proto)); + + // both ProtoTypeAdapters that set shouldUseJsonNameFieldOption to true should match in output + assertThat(GSON_WITH_JSON_NAME.toJson(proto)).isEqualTo(jsonWithJsonName); + assertThat(GSON_WITH_JSON_NAME.toJson(proto)) + .isEqualTo(GSON_WITH_SERIALIZED_NAME_AND_JSON_NAME.toJson(proto)); + + // should fail to round-trip if we serialize via the `json_name` and deserialize without it or + // vice versa + assertThat(roundTrip(GSON_PLAIN, GSON_WITH_JSON_NAME, proto)).isNotEqualTo(proto); + assertThat(roundTrip(GSON_WITH_JSON_NAME, GSON_PLAIN, proto)).isNotEqualTo(proto); + } + + @Test + public void testProtoWithAnnotationsAndJsonNames_fieldWithCustomSerializedName() { + ProtoWithAnnotationsAndJsonNames proto = + ProtoWithAnnotationsAndJsonNames.newBuilder().setAnnotationOnly("zzz").build(); + String jsonWithoutCustomName = "{\"annotationOnly\":\"zzz\"}"; + String jsonWithCustomName = "{\"bbb\":\"zzz\"}"; + + // the ProtoTypeAdapter that checks for the json name should default to the basic name + assertThat(GSON_PLAIN.toJson(proto)).isEqualTo(jsonWithoutCustomName); + assertThat(GSON_WITH_JSON_NAME.toJson(proto)).isEqualTo(GSON_PLAIN.toJson(proto)); + + // the ProtoTypeAdapter that checks for the custom serialized name should not have the same + // output as the base case + assertThat(GSON_WITH_SERIALIZED_NAME.toJson(proto)).isNotEqualTo(GSON_PLAIN.toJson(proto)); + + // both ProtoTypeAdapters that check for the custom serialized name should match in output + assertThat(GSON_WITH_SERIALIZED_NAME.toJson(proto)).isEqualTo(jsonWithCustomName); + assertThat(GSON_WITH_SERIALIZED_NAME.toJson(proto)) + .isEqualTo(GSON_WITH_SERIALIZED_NAME_AND_JSON_NAME.toJson(proto)); + + // should fail to round-trip if we serialize via the custom name and deserialize without it or + // vice versa + assertThat(roundTrip(GSON_PLAIN, GSON_WITH_SERIALIZED_NAME, proto)).isNotEqualTo(proto); + assertThat(roundTrip(GSON_WITH_SERIALIZED_NAME, GSON_PLAIN, proto)).isNotEqualTo(proto); + } + + @Test + public void testProtoWithAnnotationsAndJsonNames_fieldWithJsonNameAndCustomSerializedName() { + ProtoWithAnnotationsAndJsonNames proto = + ProtoWithAnnotationsAndJsonNames.newBuilder().setBoth("zzz").build(); + String jsonPlain = "{\"both\":\"zzz\"}"; + String jsonWithJsonName = "{\"ccc\":\"zzz\"}"; + String jsonWithCustomName = "{\"ddd\":\"zzz\"}"; + + // the three different configs serialize to three different values + assertThat(GSON_PLAIN.toJson(proto)).isEqualTo(jsonPlain); + assertThat(GSON_WITH_JSON_NAME.toJson(proto)).isEqualTo(jsonWithJsonName); + assertThat(GSON_WITH_SERIALIZED_NAME.toJson(proto)).isEqualTo(jsonWithCustomName); + + // the case where both configs are enabled will prefer the custom annotation + assertThat(GSON_WITH_SERIALIZED_NAME_AND_JSON_NAME.toJson(proto)) + .isEqualTo(GSON_WITH_SERIALIZED_NAME.toJson(proto)); + } + + private static String roundTrip(Gson jsonToProto, Gson protoToJson, String json) { + return protoToJson.toJson(jsonToProto.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)); + } + + private static ProtoWithAnnotationsAndJsonNames roundTrip( + Gson protoToJson, Gson jsonToProto, ProtoWithAnnotationsAndJsonNames proto) { + return jsonToProto.fromJson(protoToJson.toJson(proto), ProtoWithAnnotationsAndJsonNames.class); + } +} diff --git a/proto/src/test/proto/bag.proto b/proto/src/test/proto/bag.proto index 3e4769e2a8..df3eee1890 100644 --- a/proto/src/test/proto/bag.proto +++ b/proto/src/test/proto/bag.proto @@ -69,4 +69,11 @@ message ProtoWithAnnotations { } optional InnerMessage inner_message_1 = 3; optional InnerMessage inner_message_2 = 4; -} \ No newline at end of file +} + +message ProtoWithAnnotationsAndJsonNames { + optional string neither = 1; + optional string json_name_only = 2 [json_name = "aaa"]; + optional string annotation_only = 3 [(serialized_name) = "bbb"]; + optional string both = 4 [json_name = "ccc", (serialized_name) = "ddd"]; +} From 6ccba7da92a8ed929284a31fb30b5fda4d0243ad Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Thu, 13 Jun 2024 20:42:02 -0700 Subject: [PATCH 4/7] Add some metadata to Javadoc according to contributing guidelines --- .../main/java/com/google/gson/protobuf/ProtoTypeAdapter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java index 5bc8110e13..393e7c24d2 100644 --- a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java +++ b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java @@ -192,6 +192,9 @@ public Builder addSerializedEnumValueExtension( * * ...will be serialized as '{@code bar}' if `shouldUseJsonNameFieldOption` is set to `true` and * the '{@code serialized_name}' annotation is added to the adapter. + * + * @author Andrew Szeto + * @since $next-version$ */ @CanIgnoreReturnValue public Builder setShouldUseJsonNameFieldOption(boolean shouldUseJsonNameFieldOption) { From 5515f36a62f954260c0883fe2c7fc67a9698b468 Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Thu, 13 Jun 2024 20:47:46 -0700 Subject: [PATCH 5/7] Remove @author annotation in Javadoc --- .../src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java index 393e7c24d2..f03750913d 100644 --- a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java +++ b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java @@ -193,7 +193,6 @@ public Builder addSerializedEnumValueExtension( * ...will be serialized as '{@code bar}' if `shouldUseJsonNameFieldOption` is set to `true` and * the '{@code serialized_name}' annotation is added to the adapter. * - * @author Andrew Szeto * @since $next-version$ */ @CanIgnoreReturnValue From 07918d6e1891113c90df3cfb72df895096a01280 Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Thu, 20 Jun 2024 03:00:45 -0700 Subject: [PATCH 6/7] Update branch based on PR feedback on GitHub --- .../google/gson/protobuf/ProtoTypeAdapter.java | 15 ++++++++------- .../ProtosWithAnnotationsAndJsonNamesTest.java | 4 ---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java index f03750913d..30146c54fc 100644 --- a/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java +++ b/proto/src/main/java/com/google/gson/protobuf/ProtoTypeAdapter.java @@ -177,10 +177,11 @@ public Builder addSerializedEnumValueExtension( } /** - * Sets or unsets a flag that, when set, causes the adapter to use the `json_name` field option - * from a proto field for serialization. This `json_name` option is an annotation applied to - * proto fields that cannot be read from the descriptor's options - * (`FieldDescriptor::getOptions`) as it is only available via `FieldDescriptor::getJsonName`. + * Sets or unsets a flag (default false) that, when set, causes the adapter to use the {@code + * json_name} field option from a proto field for serialization. Unlike other field options that + * can be defined as annotations on a proto field, {@code json_name} cannot be accessed via a + * proto field's {@link FieldDescriptor#getOptions} and registered via {@link + * ProtoTypeAdapter.Builder#addSerializedNameExtension}. * * <p>This flag is subordinate to any custom serialized name extensions added to this adapter. * In other words, serialized name extensions take precedence over this setting. For example, a @@ -190,8 +191,8 @@ public Builder addSerializedEnumValueExtension( * string client_app_id = 1 [json_name = "foo", (serialized_name) = "bar"]; * </pre> * - * ...will be serialized as '{@code bar}' if `shouldUseJsonNameFieldOption` is set to `true` and - * the '{@code serialized_name}' annotation is added to the adapter. + * ...will be serialized as '{@code bar}' if {@code shouldUseJsonNameFieldOption} is set to + * {@code true} and the '{@code serialized_name}' annotation is added to the adapter. * * @since $next-version$ */ @@ -357,7 +358,7 @@ private String getCustSerializedName(FieldDescriptor fieldDescriptor) { return options.getExtension(extension); } } - if (fieldDescriptor.toProto().hasJsonName() && shouldUseJsonNameFieldOption) { + if (shouldUseJsonNameFieldOption && fieldDescriptor.toProto().hasJsonName()) { return fieldDescriptor.getJsonName(); } return protoFormat.to(jsonFormat, fieldDescriptor.getName()); diff --git a/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java index 6b181fa41d..abcb0c5451 100644 --- a/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java +++ b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java @@ -16,11 +16,9 @@ package com.google.gson.protobuf.functional; import static com.google.common.truth.Truth.assertThat; -// import static org.junit.Assert.assertThrows; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -// import com.google.gson.JsonParseException; import com.google.gson.protobuf.ProtoTypeAdapter; import com.google.gson.protobuf.generated.Annotations; import com.google.gson.protobuf.generated.Bag.ProtoWithAnnotationsAndJsonNames; @@ -115,12 +113,10 @@ public void testProtoWithAnnotationsAndJsonNames_unannotatedField() { // original form assertThat(gson1.toJson(proto)).isEqualTo(gson2.toJson(proto)); assertThat(roundTrip(gson1, gson2, proto)).isEqualTo(proto); - assertThat(roundTrip(gson2, gson1, proto)).isEqualTo(proto); // the same, but in the other direction assertThat(gson1.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)) .isEqualTo(gson2.fromJson(json, ProtoWithAnnotationsAndJsonNames.class)); assertThat(roundTrip(gson1, gson2, json)).isEqualTo(json); - assertThat(roundTrip(gson2, gson1, json)).isEqualTo(json); } } } From c7f37dd8813d10b488133fae3ad572d580d984a4 Mon Sep 17 00:00:00 2001 From: Andrew Szeto <andrew@jabagawee.com> Date: Fri, 21 Jun 2024 18:01:24 -0700 Subject: [PATCH 7/7] Update copyright year on test file --- .../functional/ProtosWithAnnotationsAndJsonNamesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java index abcb0c5451..7eeae44f41 100644 --- a/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java +++ b/proto/src/test/java/com/google/gson/protobuf/functional/ProtosWithAnnotationsAndJsonNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Google Inc. + * Copyright (C) 2024 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.