Add map test cases to no_field_presence_test.

Maps behave in a very interesting way if they are set to be implicit-presence
fields.

They present the possibility that the key or value (or both) can be the default
zero value. When that happens, access to the key or the value is unaffected. In
this case, presence is a bit of a meaningless concept. Zero keys are valid as
map indices, and if a map entry is set to zero, it just always exists.

Reflection is a little weird too.
- If you do reflection on a normal integer field and ask if a zero-valued field
  exists, it will tell you that it doesn't exist. This is consistent with what
  "implicit presence" means.
- If you do reflection on a zero integer field that happens to be a map key, it
  will tell you that it exists. Fetching the value of map[0] is equally valid.

(Note that this is not exactly *intended*, but it's just hard to change... and
this implementation results in simpler gencode.)

I'm adding unit tests in no_field_presence_test to cover this quirk.

PiperOrigin-RevId: 676268392
pull/18359/head
Tony Liao 2 months ago committed by Copybara-Service
parent 921b71958d
commit 27ee74e6c6
  1. 1
      src/google/protobuf/BUILD.bazel
  2. 992
      src/google/protobuf/no_field_presence_test.cc
  3. 5
      src/google/protobuf/unittest_no_field_presence.proto

@ -1782,6 +1782,7 @@ cc_test(
":protobuf", ":protobuf",
"@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/memory", "@com_google_absl//absl/memory",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:cord", "@com_google_absl//absl/strings:cord",
"@com_google_absl//absl/strings:string_view", "@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",

File diff suppressed because it is too large Load Diff

@ -100,6 +100,11 @@ message TestAllTypes {
string oneof_string = 113; string oneof_string = 113;
NestedEnum oneof_enum = 114; NestedEnum oneof_enum = 114;
} }
map<int32, bytes> map_int32_bytes = 200;
map<int32, ForeignEnum> map_int32_foreign_enum = 201;
map<int32, ForeignMessage> map_int32_foreign_message = 202;
map<int32, ExplicitForeignMessage> map_int32_explicit_foreign_message = 203;
} }
message TestProto2Required { message TestProto2Required {

Loading…
Cancel
Save