blob: 2a2d72365414d4168e04aa46046d27d2e4ab1469 [file] [log] [blame] [edit]
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
/* Test of generated code, with a special focus on features that are not used in
* descriptor.proto or conformance.proto (since these get some testing from
* 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/mem/arena.hpp"
#include "upb/message/array.h"
#include "upb/test/test.upb.h"
// Must be last.
#include "upb/port/def.inc"
#if !defined(MIN)
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
const char test_str[] = "abcdefg";
const char test_str2[] = "12345678910";
const char test_str3[] = "rstlnezxcvbnm";
const char test_str4[] = "just another test string";
const upb_StringView test_str_view = {test_str, sizeof(test_str) - 1};
const upb_StringView test_str_view2 = {test_str2, sizeof(test_str2) - 1};
const upb_StringView test_str_view3 = {test_str3, sizeof(test_str3) - 1};
const upb_StringView test_str_view4 = {test_str4, sizeof(test_str4) - 1};
const int32_t test_int32 = 10;
const int32_t test_int32_2 = -20;
const int32_t test_int32_3 = 30;
const int32_t test_int32_4 = -40;
TEST(GeneratedCode, ScalarsProto3) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
protobuf_test_messages_proto3_TestAllTypesProto3* msg2;
upb_StringView serialized;
upb_StringView val;
// Test serialization.
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int32(msg, 10);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int64(msg, 20);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint32(msg, 30);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint64(msg, 40);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_float(msg,
50.5);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_double(msg,
60.6);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_bool(msg, true);
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
msg, test_str_view);
serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
msg, arena, &serialized.size);
msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
serialized.data, serialized.size, arena);
EXPECT_EQ(10, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int32(
msg2));
EXPECT_EQ(20, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(
msg2));
EXPECT_EQ(
30,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint32(msg2));
EXPECT_EQ(
40,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg2));
EXPECT_EQ(
50.5,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_float(msg2));
EXPECT_EQ(
60.6,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_double(msg2));
EXPECT_EQ(
true,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_bool(msg2));
val = protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg2);
EXPECT_TRUE(upb_StringView_IsEqual(val, test_str_view));
// Test clear.
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_int32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int32(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_int64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_uint32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint32(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_uint64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_float(msg);
EXPECT_EQ(
0.0f,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_float(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_double(msg);
EXPECT_EQ(
0.0,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_double(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_bool(msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto3_TestAllTypesProto3_optional_bool(msg));
protobuf_test_messages_proto3_TestAllTypesProto3_clear_optional_string(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg)
.size);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, ScalarsProto2) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
protobuf_test_messages_proto2_TestAllTypesProto2* msg2;
upb_StringView serialized;
// Test hazzer and serialization.
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_int32(msg, 10);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_int64(msg, 20);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int64(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint32(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_uint32(msg, 30);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint32(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint64(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_uint64(msg, 40);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint64(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sint32(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_sint32(msg, 50);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sint32(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sint64(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_sint64(msg, 60);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sint64(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_fixed32(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_fixed32(msg,
70);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_fixed32(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_fixed64(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_fixed64(msg,
80);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_fixed64(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sfixed32(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_sfixed32(msg,
90);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sfixed32(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sfixed64(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_sfixed64(msg,
100);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_sfixed64(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_float(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_float(msg,
50.5);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_float(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_double(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_double(msg,
60.6);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_double(
msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bool(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bool(msg, true);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bool(msg));
serialized.data = protobuf_test_messages_proto2_TestAllTypesProto2_serialize(
msg, arena, &serialized.size);
msg2 = protobuf_test_messages_proto2_TestAllTypesProto2_parse(
serialized.data, serialized.size, arena);
EXPECT_EQ(10, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(
msg2));
EXPECT_EQ(20, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int64(
msg2));
EXPECT_EQ(
30,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg2));
EXPECT_EQ(
40,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint64(msg2));
EXPECT_EQ(
50,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_sint32(msg2));
EXPECT_EQ(
60,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_sint64(msg2));
EXPECT_EQ(
70,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_fixed32(msg2));
EXPECT_EQ(
80,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_fixed64(msg2));
EXPECT_EQ(
90,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_sfixed32(msg2));
EXPECT_EQ(
100,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_sfixed64(msg2));
EXPECT_EQ(
50.5,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_float(msg2));
EXPECT_EQ(
60.6,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_double(msg2));
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bool(msg2));
// Test clear.
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int64(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint32(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint64(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_uint64(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_float(msg);
EXPECT_EQ(
0.0f,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_float(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_float(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_double(msg);
EXPECT_EQ(
0.0,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_double(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_double(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_bool(msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bool(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bool(msg));
upb_Arena_Free(arena);
}
TEST(GeneratedCode, RepeatedClear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
size_t len = 0;
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 2,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 3,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_add_repeated_int32(msg, 4,
arena);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(3, len);
protobuf_test_messages_proto2_TestAllTypesProto2_clear_repeated_int32(msg);
protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg, &len);
EXPECT_EQ(0, len);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, Clear) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
// Test clear.
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_int32(msg, 1);
EXPECT_TRUE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
EXPECT_FALSE(
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_int32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_int64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint32(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_uint64(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint64(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_float(msg);
EXPECT_EQ(
0.0f,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_float(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_double(msg);
EXPECT_EQ(
0.0,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_double(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_bool(msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bool(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_string(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg)
.size);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, Bytes) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
protobuf_test_messages_proto2_TestAllTypesProto2* msg2;
upb_StringView serialized;
const char data[] = "ABCDEF";
upb_StringView bytes = upb_StringView_FromString(data);
upb_StringView val;
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bytes(msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bytes(msg,
bytes);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bytes(msg));
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
msg));
protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_string(
msg, test_str_view);
EXPECT_EQ(
true,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
msg));
serialized.data = protobuf_test_messages_proto2_TestAllTypesProto2_serialize(
msg, arena, &serialized.size);
msg2 = protobuf_test_messages_proto2_TestAllTypesProto2_parse(
serialized.data, serialized.size, arena);
EXPECT_EQ(bytes.size,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bytes(msg)
.size);
EXPECT_EQ(
0, memcmp(bytes.data,
protobuf_test_messages_proto2_TestAllTypesProto2_optional_bytes(
msg)
.data,
bytes.size));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_bytes(msg);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_bytes(msg));
val = protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg2);
EXPECT_TRUE(upb_StringView_IsEqual(val, test_str_view));
protobuf_test_messages_proto2_TestAllTypesProto2_clear_optional_string(msg);
EXPECT_EQ(
0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg)
.size);
EXPECT_EQ(
false,
protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
msg));
upb_Arena_Free(arena);
}
TEST(GeneratedCode, UTF8) {
const char invalid_utf8[] = "\xff";
const upb_StringView invalid_utf8_view =
upb_StringView_FromDataAndSize(invalid_utf8, 1);
upb_Arena* arena = upb_Arena_New();
upb_StringView serialized;
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
protobuf_test_messages_proto3_TestAllTypesProto3* msg2;
protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
msg, invalid_utf8_view);
serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
msg, arena, &serialized.size);
msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
serialized.data, serialized.size, arena);
EXPECT_EQ(nullptr, msg2);
upb_Arena_Free(arena);
}
static void check_string_map_empty(
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
size_t iter = kUpb_Map_Begin;
EXPECT_EQ(
0,
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
msg));
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter));
}
static void check_string_map_one_entry(
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry*
const_ent;
size_t iter;
upb_StringView str;
EXPECT_EQ(
1,
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
msg));
EXPECT_TRUE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
msg, test_str_view, &str));
EXPECT_TRUE(upb_StringView_IsEqual(str, test_str_view2));
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
msg, test_str_view3, &str));
/* Test that iteration reveals a single k/v pair in the map. */
iter = kUpb_Map_Begin;
const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter);
ASSERT_NE(nullptr, const_ent);
EXPECT_TRUE(upb_StringView_IsEqual(
test_str_view,
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
const_ent)));
EXPECT_TRUE(upb_StringView_IsEqual(
test_str_view2,
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
const_ent)));
const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter);
EXPECT_EQ(nullptr, const_ent);
}
TEST(GeneratedCode, StringDoubleMap) {
upb_Arena* arena = upb_Arena_New();
upb_StringView serialized;
upb_test_MapTest* msg = upb_test_MapTest_new(arena);
upb_test_MapTest* msg2;
double val;
upb_test_MapTest_map_string_double_set(msg, test_str_view, 1.5, arena);
ASSERT_NE(nullptr, msg);
EXPECT_TRUE(upb_test_MapTest_map_string_double_get(msg, test_str_view, &val));
EXPECT_EQ(1.5, val);
val = 0;
serialized.data = upb_test_MapTest_serialize(msg, arena, &serialized.size);
EXPECT_NE(nullptr, serialized.data);
msg2 = upb_test_MapTest_parse(serialized.data, serialized.size, arena);
ASSERT_NE(nullptr, msg2);
EXPECT_TRUE(
upb_test_MapTest_map_string_double_get(msg2, test_str_view, &val));
EXPECT_EQ(1.5, val);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, StringMap) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry*
const_ent;
size_t iter, count;
check_string_map_empty(msg);
/* Set map[test_str_view] = test_str_view2 */
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view, test_str_view2, arena);
check_string_map_one_entry(msg);
/* Deleting a non-existent key does nothing. */
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
msg, test_str_view3));
check_string_map_one_entry(msg);
/* Deleting the key sets the map back to empty. */
EXPECT_TRUE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
msg, test_str_view));
check_string_map_empty(msg);
/* Set two keys this time:
* map[test_str_view] = test_str_view2
* map[test_str_view3] = test_str_view4
*/
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view, test_str_view2, arena);
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
msg, test_str_view3, test_str_view4, arena);
/* Test iteration */
iter = kUpb_Map_Begin;
count = 0;
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
msg, &iter)) != nullptr) {
upb_StringView key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
const_ent);
upb_StringView val =
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
const_ent);
count++;
if (upb_StringView_IsEqual(key, test_str_view)) {
EXPECT_TRUE(upb_StringView_IsEqual(val, test_str_view2));
} else {
EXPECT_TRUE(upb_StringView_IsEqual(key, test_str_view3));
EXPECT_TRUE(upb_StringView_IsEqual(val, test_str_view4));
}
}
EXPECT_EQ(2, count);
/* Clearing the map goes back to empty. */
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_clear(msg);
check_string_map_empty(msg);
upb_Arena_Free(arena);
}
static void check_int32_map_empty(
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
size_t iter = kUpb_Map_Begin;
EXPECT_EQ(
0, protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
msg));
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter));
}
static void check_int32_map_one_entry(
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry*
const_ent;
size_t iter;
int32_t val;
EXPECT_EQ(
1, protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
msg));
EXPECT_TRUE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
msg, test_int32, &val));
EXPECT_EQ(val, test_int32_2);
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
msg, test_int32_3, &val));
/* Test that iteration reveals a single k/v pair in the map. */
iter = kUpb_Map_Begin;
const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter);
ASSERT_NE(nullptr, const_ent);
EXPECT_EQ(
test_int32,
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
const_ent));
EXPECT_EQ(
test_int32_2,
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
const_ent));
const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter);
EXPECT_EQ(nullptr, const_ent);
}
TEST(GeneratedCode, Int32Map) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry*
const_ent;
size_t iter, count;
check_int32_map_empty(msg);
/* Set map[test_int32] = test_int32_2 */
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32, test_int32_2, arena);
check_int32_map_one_entry(msg);
/* Deleting a non-existent key does nothing. */
EXPECT_FALSE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
msg, test_int32_3));
check_int32_map_one_entry(msg);
/* Deleting the key sets the map back to empty. */
EXPECT_TRUE(
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
msg, test_int32));
check_int32_map_empty(msg);
/* Set two keys this time:
* map[test_int32] = test_int32_2
* map[test_int32_3] = test_int32_4
*/
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32, test_int32_2, arena);
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
msg, test_int32_3, test_int32_4, arena);
/* Test iteration */
iter = kUpb_Map_Begin;
count = 0;
while (
(const_ent =
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
msg, &iter)) != nullptr) {
int32_t key =
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
const_ent);
int32_t val =
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
const_ent);
count++;
if (key == test_int32) {
EXPECT_EQ(val, test_int32_2);
} else {
EXPECT_EQ(key, test_int32_3);
EXPECT_EQ(val, test_int32_4);
}
}
EXPECT_EQ(2, count);
/* Clearing the map goes back to empty. */
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_clear(msg);
check_int32_map_empty(msg);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, TestRepeated) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
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(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);
}
TEST(GeneratedCode, Issue9440) {
upb::Arena arena;
upb_test_HelloRequest* msg = upb_test_HelloRequest_new(arena.ptr());
upb_test_HelloRequest_set_id(msg, 8);
EXPECT_EQ(8, upb_test_HelloRequest_id(msg));
char str[] = "1";
upb_test_HelloRequest_set_version(msg, upb_StringView{str, strlen(str)});
EXPECT_EQ(8, upb_test_HelloRequest_id(msg));
}
TEST(GeneratedCode, NullDecodeBuffer) {
upb_Arena* arena = upb_Arena_New();
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
protobuf_test_messages_proto3_TestAllTypesProto3_parse(nullptr, 0, arena);
size_t size;
ASSERT_NE(nullptr, msg);
protobuf_test_messages_proto3_TestAllTypesProto3_serialize(msg, arena, &size);
EXPECT_EQ(0, size);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, StatusTruncation) {
int i, j;
upb_Status status;
upb_Status status2;
for (i = 0; i < _kUpb_Status_MaxMessage + 20; i++) {
char* msg = static_cast<char*>(malloc(i + 1));
int end;
char ch = (i % 96) + 33; /* Cycle through printable chars. */
for (j = 0; j < i; j++) {
msg[j] = ch;
}
msg[i] = '\0';
upb_Status_SetErrorMessage(&status, msg);
upb_Status_SetErrorFormat(&status2, "%s", msg);
end = MIN(i, _kUpb_Status_MaxMessage - 1);
EXPECT_EQ(end, strlen(status.msg));
EXPECT_EQ(end, strlen(status2.msg));
for (j = 0; j < end; j++) {
EXPECT_EQ(ch, status.msg[j]);
EXPECT_EQ(ch, status2.msg[j]);
}
free(msg);
}
}
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, 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);
// Try the same, but with a size so small that aligning up will overflow.
arena = upb_Arena_Init(unaligned_buf_ptr, 5, &upb_alloc_global);
mem = static_cast<char*>(upb_Arena_Malloc(arena, 5));
EXPECT_EQ(0, reinterpret_cast<uintptr_t>(mem) & low_bits);
upb_Arena_Free(arena);
}
TEST(GeneratedCode, Extensions) {
upb::Arena arena;
upb_test_ModelExtension1* extension1 =
upb_test_ModelExtension1_new(arena.ptr());
upb_test_ModelExtension1_set_str(extension1,
upb_StringView_FromString("Hello"));
upb_test_ModelExtension2* extension2 =
upb_test_ModelExtension2_new(arena.ptr());
upb_test_ModelExtension2_set_i(extension2, 5);
upb_test_ModelWithExtensions* msg1 =
upb_test_ModelWithExtensions_new(arena.ptr());
upb_test_ModelWithExtensions* msg2 =
upb_test_ModelWithExtensions_new(arena.ptr());
// msg1: [extension1, extension2]
upb_test_ModelExtension1_set_model_ext(msg1, extension1, arena.ptr());
upb_test_ModelExtension2_set_model_ext(msg1, extension2, arena.ptr());
// msg2: [extension2, extension1]
upb_test_ModelExtension2_set_model_ext(msg2, extension2, arena.ptr());
upb_test_ModelExtension1_set_model_ext(msg2, extension1, arena.ptr());
size_t size1, size2;
int opts = kUpb_EncodeOption_Deterministic;
char* pb1 = upb_test_ModelWithExtensions_serialize_ex(msg1, opts, arena.ptr(),
&size1);
char* pb2 = upb_test_ModelWithExtensions_serialize_ex(msg2, opts, arena.ptr(),
&size2);
ASSERT_EQ(size1, size2);
ASSERT_EQ(0, memcmp(pb1, pb2, size1));
}