Skip to content

Commit 0f3dd06

Browse files
Add conformance test cases about handling of google.protobuf.Empty inside any Any in JSON.
As of today: - GoProto and C# serialize google.protobuf.Empty-packed-into-Any with the `"value":{}` field set - Only Go, C# and Swift accept that shape at parse time In an attempt to make spec match reality, the public ProtoJSON documentation has now been clarified to match the common behavior that nearly all implementations have in practice. Note that this conformance test added is only mandating that implementations: 1) Accept it without the `"value":{}` set 2) Serialize it without it set (by virtue of the round trip coming back to C++Proto in the test harness which does not accept it). A test that confirms an implementation affirmatively rejects if the "value":{} is set is not added here; especially in the near term it is sensible for implementations like Go and C# to locally continue to accept that shape for backwards compatibility reasons within the same language, as long as it emits without it by default so that other languages can parse what it emits. For that reason, a test affirming a parse failure when it is present is not added to the conformance test suite failure today. #24445 PiperOrigin-RevId: 854155587
1 parent eba53e8 commit 0f3dd06

8 files changed

Lines changed: 31 additions & 2 deletions

File tree

conformance/binary_json_conformance_suite.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <string>
1717
#include <type_traits>
1818
#include <utility>
19-
#include <vector>
2019

2120
#include "absl/log/absl_check.h"
2221
#include "absl/log/absl_log.h"
@@ -3685,6 +3684,22 @@ void BinaryAndJsonConformanceSuiteImpl<MessageType>::RunJsonTestsForAny() {
36853684
})",
36863685
R"(
36873686
)");
3687+
3688+
// google.protobuf.Empty packed into an Any, implementations must accept it
3689+
// without the "value" field set. This also confirms that what they round trip
3690+
// does not have `"value":{}` set on it, since the test harness uses the C++
3691+
// JSON parser which will reject it.
3692+
RunValidJsonTest("AnyEmpty", REQUIRED,
3693+
R"({
3694+
"optionalAny": {
3695+
"@type": "type.googleapis.com/google.protobuf.Empty"
3696+
}
3697+
})",
3698+
R"(
3699+
optional_any: {
3700+
[type.googleapis.com/google.protobuf.Empty] {}
3701+
}
3702+
)");
36883703
}
36893704

36903705
template <typename MessageType>

conformance/failure_list_csharp.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ Required.Editions_Proto3.ProtobufInput.UnknownOrdering.ProtobufOutput
4040
Required.*.ProtobufInput.BadTag_FieldNumberTooHigh # Should have failed to parse, but didn't.
4141
Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't.
4242
Required.*.ProtobufInput.BadTag_OverlongVarint # Should have failed to parse, but didn't.
43-
43+
Required.*.JsonInput.AnyEmpty.*

editions/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ proto_library(
258258
deps = [
259259
"//:any_proto",
260260
"//:duration_proto",
261+
"//:empty_proto",
261262
"//:field_mask_proto",
262263
"//:struct_proto",
263264
"//:timestamp_proto",

editions/golden/edition2023_transform/test_messages_proto3.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package protobuf_test_messages.proto3;
1818

1919
import "google/protobuf/any.proto";
2020
import "google/protobuf/duration.proto";
21+
import "google/protobuf/empty.proto";
2122
import "google/protobuf/field_mask.proto";
2223
import "google/protobuf/struct.proto";
2324
import "google/protobuf/timestamp.proto";
@@ -255,13 +256,15 @@ message TestAllTypesProto3 {
255256
google.protobuf.Any optional_any = 305;
256257
google.protobuf.Value optional_value = 306;
257258
google.protobuf.NullValue optional_null_value = 307;
259+
google.protobuf.Empty optional_empty = 308;
258260
repeated google.protobuf.Duration repeated_duration = 311;
259261
repeated google.protobuf.Timestamp repeated_timestamp = 312;
260262
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
261263
repeated google.protobuf.Struct repeated_struct = 324;
262264
repeated google.protobuf.Any repeated_any = 315;
263265
repeated google.protobuf.Value repeated_value = 316;
264266
repeated google.protobuf.ListValue repeated_list_value = 317;
267+
repeated google.protobuf.Empty repeated_empty = 318;
265268

266269
// Test field-name-to-JSON-name convention.
267270
// (protobuf says names can be any valid C/C++ identifier.)

editions/golden/edition2024_transform/test_messages_proto3.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package protobuf_test_messages.proto3;
1919

2020
import "google/protobuf/any.proto";
2121
import "google/protobuf/duration.proto";
22+
import "google/protobuf/empty.proto";
2223
import "google/protobuf/field_mask.proto";
2324
import "google/protobuf/struct.proto";
2425
import "google/protobuf/timestamp.proto";
@@ -268,13 +269,15 @@ message TestAllTypesProto3 {
268269
google.protobuf.Any optional_any = 305;
269270
google.protobuf.Value optional_value = 306;
270271
google.protobuf.NullValue optional_null_value = 307;
272+
google.protobuf.Empty optional_empty = 308;
271273
repeated google.protobuf.Duration repeated_duration = 311;
272274
repeated google.protobuf.Timestamp repeated_timestamp = 312;
273275
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
274276
repeated google.protobuf.Struct repeated_struct = 324;
275277
repeated google.protobuf.Any repeated_any = 315;
276278
repeated google.protobuf.Value repeated_value = 316;
277279
repeated google.protobuf.ListValue repeated_list_value = 317;
280+
repeated google.protobuf.Empty repeated_empty = 318;
278281

279282
// Test field-name-to-JSON-name convention.
280283
// (protobuf says names can be any valid C/C++ identifier.)

editions/golden/test_messages_proto3_editions.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package protobuf_test_messages.editions.proto3;
1818

1919
import "google/protobuf/any.proto";
2020
import "google/protobuf/duration.proto";
21+
import "google/protobuf/empty.proto";
2122
import "google/protobuf/field_mask.proto";
2223
import "google/protobuf/struct.proto";
2324
import "google/protobuf/timestamp.proto";
@@ -255,13 +256,15 @@ message TestAllTypesProto3 {
255256
google.protobuf.Any optional_any = 305;
256257
google.protobuf.Value optional_value = 306;
257258
google.protobuf.NullValue optional_null_value = 307;
259+
google.protobuf.Empty optional_empty = 308;
258260
repeated google.protobuf.Duration repeated_duration = 311;
259261
repeated google.protobuf.Timestamp repeated_timestamp = 312;
260262
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
261263
repeated google.protobuf.Struct repeated_struct = 324;
262264
repeated google.protobuf.Any repeated_any = 315;
263265
repeated google.protobuf.Value repeated_value = 316;
264266
repeated google.protobuf.ListValue repeated_list_value = 317;
267+
repeated google.protobuf.Empty repeated_empty = 318;
265268

266269
// Test field-name-to-JSON-name convention.
267270
// (protobuf says names can be any valid C/C++ identifier.)

src/google/protobuf/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,7 @@ proto_library(
13741374
deps = [
13751375
":any_proto",
13761376
":duration_proto",
1377+
":empty_proto",
13771378
":field_mask_proto",
13781379
":struct_proto",
13791380
":timestamp_proto",

src/google/protobuf/test_messages_proto3.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ option optimize_for = SPEED;
2424

2525
import "google/protobuf/any.proto";
2626
import "google/protobuf/duration.proto";
27+
import "google/protobuf/empty.proto";
2728
import "google/protobuf/field_mask.proto";
2829
import "google/protobuf/struct.proto";
2930
import "google/protobuf/timestamp.proto";
@@ -212,6 +213,7 @@ message TestAllTypesProto3 {
212213
google.protobuf.Any optional_any = 305;
213214
google.protobuf.Value optional_value = 306;
214215
google.protobuf.NullValue optional_null_value = 307;
216+
google.protobuf.Empty optional_empty = 308;
215217

216218
repeated google.protobuf.Duration repeated_duration = 311;
217219
repeated google.protobuf.Timestamp repeated_timestamp = 312;
@@ -220,6 +222,7 @@ message TestAllTypesProto3 {
220222
repeated google.protobuf.Any repeated_any = 315;
221223
repeated google.protobuf.Value repeated_value = 316;
222224
repeated google.protobuf.ListValue repeated_list_value = 317;
225+
repeated google.protobuf.Empty repeated_empty = 318;
223226

224227
// Test field-name-to-JSON-name convention.
225228
// (protobuf says names can be any valid C/C++ identifier.)

0 commit comments

Comments
 (0)