Add private accessors for repeated array get to be used by C++ RepeatedField implementation.

PiperOrigin-RevId: 526656160
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 9fa51d0bc9
commit 30af08f511
  1. 55
      upb/test/test_generated_code.cc
  2. 1
      upbc/BUILD
  3. 5
      upbc/names.cc
  4. 7
      upbc/names.h
  5. 44
      upbc/protoc-gen-upb.cc

@ -30,9 +30,16 @@
* upb/def.c and tests/conformance_upb.c, respectively).
*/
#include <cstddef>
#include <cstdint>
#include "gtest/gtest.h"
#include "google/protobuf/test_messages_proto2.upb.h"
#include "google/protobuf/test_messages_proto3.upb.h"
#include "upb/base/status.h"
#include "upb/base/string_view.h"
#include "upb/collections/array.h"
#include "upb/mem/arena.h"
#include "upb/test/test.upb.h"
#include "upb/upb.hpp"
@ -75,7 +82,7 @@ TEST(GeneratedCode, ScalarsProto3) {
50.5);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_double(msg,
60.6);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_bool(msg, 1);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_bool(msg, true);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
msg, test_str_view);
@ -258,7 +265,7 @@ TEST(GeneratedCode, ScalarsProto2) {
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bool(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bool(msg, 1);
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bool(msg, true);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bool(msg));
@ -632,7 +639,7 @@ TEST(GeneratedCode, StringMap) {
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter)) != NULL) {
msg, &iter)) != nullptr) {
upb_StringView key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
const_ent);
@ -753,7 +760,7 @@ TEST(GeneratedCode, Int32Map) {
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter)) != NULL) {
msg, &iter)) != nullptr) {
int32_t key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
const_ent);
@ -786,14 +793,35 @@ TEST(GeneratedCode, TestRepeated) {
size_t size;
const int* elems;
EXPECT_EQ(
_protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32_upb_array(
msg, &size),
nullptr);
protobuf_test_messages_proto3_TestAllTypesProto3_add_repeated_int32(msg, 5,
arena);
EXPECT_NE(
_protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32_upb_array(
msg, &size),
nullptr);
elems = protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32(
msg, &size);
EXPECT_EQ(1, size);
EXPECT_EQ(5, elems[0]);
EXPECT_EQ(size, 1);
EXPECT_EQ(elems[0], 5);
const upb_Array* arr =
_protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32_upb_array(
msg, &size);
EXPECT_EQ(size, 1);
upb_Array* mutable_arr =
_protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32_mutable_upb_array(
msg, &size, arena);
EXPECT_EQ(mutable_arr, arr);
EXPECT_EQ(upb_Array_Size(arr), 1);
EXPECT_EQ(size, 1);
upb_Arena_Free(arena);
}
@ -811,7 +839,7 @@ TEST(GeneratedCode, Issue9440) {
TEST(GeneratedCode, NullDecodeBuffer) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_parse(NULL, 0, arena);
protobuf_test_messages_proto3_TestAllTypesProto3_parse(nullptr, 0, arena);
size_t size;
ASSERT_NE(nullptr, msg);
@ -849,24 +877,13 @@ TEST(GeneratedCode, StatusTruncation) {
}
}
static void decrement_int(void* ptr) {
int* iptr = static_cast<int*>(ptr);
(*iptr)--;
}
/* Do nothing allocator for testing */
static void* test_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize,
size_t size) {
return upb_alloc_global.func(alloc, ptr, oldsize, size);
}
TEST(GeneratedCode, ArenaUnaligned) {
char buf1[1024];
// Force the pointer to be unaligned.
uintptr_t low_bits = UPB_MALLOC_ALIGN - 1;
char* unaligned_buf_ptr = (char*)((uintptr_t)buf1 | low_bits);
upb_Arena* arena = upb_Arena_Init(
unaligned_buf_ptr, &buf1[sizeof(buf1)] - unaligned_buf_ptr, NULL);
unaligned_buf_ptr, &buf1[sizeof(buf1)] - unaligned_buf_ptr, nullptr);
char* mem = static_cast<char*>(upb_Arena_Malloc(arena, 5));
EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) & low_bits);
upb_Arena_Free(arena);

@ -198,6 +198,7 @@ bootstrap_cc_library(
copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//protos_generator:__pkg__"],
deps = [
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",

@ -30,6 +30,7 @@
#include <string>
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"
#include "upb/reflection/def.hpp"
@ -45,6 +46,10 @@ static constexpr absl::string_view kDeleteMethodPrefix = "delete_";
static constexpr absl::string_view kAddToRepeatedMethodPrefix = "add_";
static constexpr absl::string_view kResizeArrayMethodPrefix = "resize_";
const absl::string_view kRepeatedFieldArrayGetterPostfix = "upb_array";
const absl::string_view kRepeatedFieldMutableArrayGetterPostfix =
"mutable_upb_array";
// List of generated accessor prefixes to check against.
// Example:
// optional repeated string phase = 236;

@ -30,7 +30,9 @@
#include <string>
#include "absl/base/attributes.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"
#include "upb/reflection/def.hpp"
@ -58,6 +60,11 @@ std::string ResolveFieldName(upb::FieldDefPtr field,
// Returns field map by name to use for conflict checks.
NameToFieldDefMap CreateFieldNameMap(upb::MessageDefPtr message);
// Private array getter name postfix for repeated fields.
ABSL_CONST_INIT extern const absl::string_view kRepeatedFieldArrayGetterPostfix;
ABSL_CONST_INIT extern const absl::string_view
kRepeatedFieldMutableArrayGetterPostfix;
} // namespace upbc
#endif // UPB_PROTOS_GENERATOR_NAMES_H

@ -519,6 +519,10 @@ void GenerateRepeatedGetters(upb::FieldDefPtr field, const DefPoolPair& pools,
absl::string_view msg_name,
const NameToFieldDefMap& field_names,
const Options& options, Output& output) {
// Generate getter returning first item and size.
//
// Example:
// UPB_INLINE const struct Bar* const* name(const Foo* msg, size_t* size)
output(
R"cc(
UPB_INLINE $0 const* $1_$2(const $1* msg, size_t* size) {
@ -533,8 +537,44 @@ void GenerateRepeatedGetters(upb::FieldDefPtr field, const DefPoolPair& pools,
}
}
)cc",
CTypeConst(field), msg_name, ResolveFieldName(field, field_names),
FieldInitializer(pools, field, options));
CTypeConst(field), // $0
msg_name, // $1
ResolveFieldName(field, field_names), // $2
FieldInitializer(pools, field, options) // #3
);
// Generate private getter returning array or NULL for immutable and upb_Array
// for mutable.
//
// Example:
// UPB_INLINE const upb_Array* _name_upbarray(size_t* size)
// UPB_INLINE upb_Array* _name_mutable_upbarray(size_t* size)
output(
R"cc(
UPB_INLINE const upb_Array* _$1_$2_$4(const $1* msg, size_t* size) {
const upb_MiniTableField field = $3;
const upb_Array* arr = upb_Message_GetArray(msg, &field);
if (size) {
*size = arr ? arr->size : 0;
}
return arr;
}
UPB_INLINE upb_Array* _$1_$2_$5(const $1* msg, size_t* size, upb_Arena* arena) {
const upb_MiniTableField field = $3;
upb_Array* arr = upb_Message_GetOrCreateMutableArray(
(upb_Message*)msg, &field, arena);
if (size) {
*size = arr ? arr->size : 0;
}
return arr;
}
)cc",
CTypeConst(field), // $0
msg_name, // $1
ResolveFieldName(field, field_names), // $2
FieldInitializer(pools, field, options), // $3
kRepeatedFieldArrayGetterPostfix, // $4
kRepeatedFieldMutableArrayGetterPostfix // $5
);
}
void GenerateScalarGetters(upb::FieldDefPtr field, const DefPoolPair& pools,

Loading…
Cancel
Save