From 0f585c69af91c9e839e7955e4dc432a35108dc95 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Mon, 3 Oct 2022 09:36:17 -0700 Subject: [PATCH] stop requiring extension fields to have a synthetic oneof https://github.com/protocolbuffers/upb/issues/812 PiperOrigin-RevId: 478527073 --- BUILD | 31 +++++++++++++++++++++++++++++++ upb/proto3_test.cc | 37 +++++++++++++++++++++++++++++++++++++ upb/proto3_test.proto | 22 ++++++++++++++++++++++ upb/reflection/field_def.c | 13 +++++++++---- 4 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 upb/proto3_test.cc create mode 100644 upb/proto3_test.proto diff --git a/BUILD b/BUILD index b8358297e9..64af96945a 100644 --- a/BUILD +++ b/BUILD @@ -637,6 +637,25 @@ upb_proto_library( deps = [":msg_test_proto"], ) +proto_library( + name = "proto3_test_proto", + testonly = 1, + srcs = ["upb/proto3_test.proto"], + deps = ["@com_google_protobuf//:descriptor_proto"], +) + +upb_proto_library( + name = "proto3_test_upb_proto", + testonly = 1, + deps = [":proto3_test_proto"], +) + +upb_proto_reflection_library( + name = "proto3_test_upb_proto_reflection", + testonly = 1, + deps = [":proto3_test_proto"], +) + upb_proto_reflection_library( name = "msg_test_upb_proto_reflection", testonly = 1, @@ -685,6 +704,18 @@ cc_test( ], ) +cc_test( + name = "proto3_test", + srcs = ["upb/proto3_test.cc"], + copts = UPB_DEFAULT_CPPOPTS, + deps = [ + ":proto3_test_upb_proto", + ":proto3_test_upb_proto_reflection", + ":reflection", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "test_cpp", srcs = ["upb/test_cpp.cc"], diff --git a/upb/proto3_test.cc b/upb/proto3_test.cc new file mode 100644 index 0000000000..76700f86b1 --- /dev/null +++ b/upb/proto3_test.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2009-2021, Google LLC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Google LLC nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gtest/gtest.h" +#include "upb/proto3_test.upb.h" +#include "upb/proto3_test.upbdefs.h" +#include "upb/reflection/def.hpp" + +TEST(Proto3Test, SyntheticOneofExtension) { + upb::DefPool defpool; + upb::MessageDefPtr md(upb_test_TestMessage3_getmsgdef(defpool.ptr())); + ASSERT_EQ(md.field_count(), 6); +} diff --git a/upb/proto3_test.proto b/upb/proto3_test.proto new file mode 100644 index 0000000000..f83a8b8c4b --- /dev/null +++ b/upb/proto3_test.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package upb.test; + +import "google/protobuf/descriptor.proto"; + +extend google.protobuf.MessageOptions { + optional string my_option = 51235; +} + +message MyMessage3 { + option (my_option) = "Hello world!"; +} + +message TestMessage3 { + optional int32 i32 = 1; + repeated int32 r_i32 = 2; + optional string str = 3; + repeated string r_str = 4; + optional TestMessage3 msg = 5; + repeated TestMessage3 r_msg = 6; +} diff --git a/upb/reflection/field_def.c b/upb/reflection/field_def.c index 490c861cdf..08a4e4186b 100644 --- a/upb/reflection/field_def.c +++ b/upb/reflection/field_def.c @@ -648,10 +648,6 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, bool ok = _upb_OneofDef_Insert(oneof, f, name.data, name.size, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); - } else if (f->proto3_optional_) { - _upb_DefBuilder_Errf(ctx, - "field with proto3_optional was not in a oneof (%s)", - f->full_name); } UBP_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); @@ -694,6 +690,15 @@ static void _upb_FieldDef_CreateNotExt( _upb_FieldDef_Create(ctx, prefix, field_proto, m, f); f->is_extension_ = false; + if (!google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + if (f->proto3_optional_) { + _upb_DefBuilder_Errf( + ctx, + "non-extension field (%s) with proto3_optional was not in a oneof", + f->full_name); + } + } + _upb_MessageDef_InsertField(ctx, m, f); if (!ctx->layout) return;