Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
12 KiB
259 lines
12 KiB
2 years ago
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
/* Test of mini table accessors.
|
||
|
*
|
||
|
* Messages are created and mutated using generated code, and then
|
||
|
* accessed through reflective APIs exposed through mini table accessors.
|
||
|
*/
|
||
|
|
||
|
#include "upb/message/copy.h"
|
||
|
|
||
|
#include "gtest/gtest.h"
|
||
|
#include "google/protobuf/test_messages_proto2.upb.h"
|
||
|
#include "google/protobuf/test_messages_proto3.upb.h"
|
||
|
#include "upb/base/string_view.h"
|
||
|
#include "upb/collections/array.h"
|
||
|
#include "upb/collections/map.h"
|
||
|
#include "upb/mem/arena.h"
|
||
|
#include "upb/message/accessors.h"
|
||
|
#include "upb/mini_table/common.h"
|
||
|
#include "upb/mini_table/encode_internal.hpp"
|
||
|
#include "upb/mini_table/field_internal.h"
|
||
|
#include "upb/test/test.upb.h"
|
||
|
#include "upb/upb.h"
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
// Proto2 test messages field numbers used for reflective access.
|
||
|
const uint32_t kFieldOptionalInt32 = 1;
|
||
|
const uint32_t kFieldOptionalString = 14;
|
||
|
const uint32_t kFieldOptionalNestedMessage = 18;
|
||
|
|
||
|
const char kTestStr1[] = "Hello1";
|
||
|
const char kTestStr2[] = "HelloWorld2";
|
||
|
const int32_t kTestInt32 = 567;
|
||
|
const int32_t kTestNestedInt32 = 123;
|
||
|
|
||
|
const upb_MiniTableField* find_proto2_field(int field_number) {
|
||
|
return upb_MiniTable_FindFieldByNumber(
|
||
|
&protobuf_test_messages_proto2_TestAllTypesProto2_msg_init, field_number);
|
||
|
}
|
||
|
|
||
|
TEST(GeneratedCode, DeepCloneMessageScalarAndString) {
|
||
|
upb_Arena* source_arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena);
|
||
|
const upb_MiniTableField* optional_int32_field =
|
||
|
find_proto2_field(kFieldOptionalInt32);
|
||
|
const upb_MiniTableField* optional_string_field =
|
||
|
find_proto2_field(kFieldOptionalString);
|
||
|
upb_Message_SetInt32(msg, optional_int32_field, kTestInt32, nullptr);
|
||
|
char* string_in_arena =
|
||
|
(char*)upb_Arena_Malloc(source_arena, sizeof(kTestStr1));
|
||
|
memcpy(string_in_arena, kTestStr1, sizeof(kTestStr1));
|
||
|
upb_Message_SetString(
|
||
|
msg, optional_string_field,
|
||
|
upb_StringView_FromDataAndSize(string_in_arena, sizeof(kTestStr1) - 1),
|
||
|
source_arena);
|
||
|
upb_Arena* arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* clone =
|
||
|
(protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_DeepClone(
|
||
|
msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init,
|
||
|
arena);
|
||
|
// After cloning overwrite values and destroy source arena for MSAN.
|
||
|
memset(string_in_arena, 0, sizeof(kTestStr1));
|
||
|
upb_Arena_Free(source_arena);
|
||
|
EXPECT_TRUE(upb_Message_HasField(clone, optional_int32_field));
|
||
|
EXPECT_EQ(upb_Message_GetInt32(clone, optional_int32_field, 0), kTestInt32);
|
||
|
EXPECT_TRUE(upb_Message_HasField(clone, optional_string_field));
|
||
|
EXPECT_EQ(upb_Message_GetString(clone, optional_string_field,
|
||
|
upb_StringView_FromDataAndSize(nullptr, 0))
|
||
|
.size,
|
||
|
sizeof(kTestStr1) - 1);
|
||
|
EXPECT_TRUE(upb_StringView_IsEqual(
|
||
|
upb_Message_GetString(clone, optional_string_field,
|
||
|
upb_StringView_FromDataAndSize(nullptr, 0)),
|
||
|
upb_StringView_FromString(kTestStr1)));
|
||
|
upb_Arena_Free(arena);
|
||
|
}
|
||
|
|
||
|
TEST(GeneratedCode, DeepCloneMessageSubMessage) {
|
||
|
upb_Arena* source_arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena);
|
||
|
const upb_MiniTableField* nested_message_field =
|
||
|
find_proto2_field(kFieldOptionalNestedMessage);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage* nested =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_new(
|
||
|
source_arena);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(
|
||
|
nested, kTestNestedInt32);
|
||
|
upb_Message_SetMessage(
|
||
|
msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init,
|
||
|
nested_message_field, nested);
|
||
|
upb_Arena* arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* clone =
|
||
|
(protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_DeepClone(
|
||
|
msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init,
|
||
|
arena);
|
||
|
// After cloning overwrite values and destroy source arena for MSAN.
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(nested,
|
||
|
0);
|
||
|
upb_Arena_Free(source_arena);
|
||
|
EXPECT_TRUE(upb_Message_HasField(clone, nested_message_field));
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage*
|
||
|
cloned_nested =
|
||
|
(protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage*)
|
||
|
upb_Message_GetMessage(clone, nested_message_field, nullptr);
|
||
|
EXPECT_EQ(protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_a(
|
||
|
cloned_nested),
|
||
|
kTestNestedInt32);
|
||
|
upb_Arena_Free(arena);
|
||
|
}
|
||
|
|
||
|
TEST(GeneratedCode, DeepCloneMessageMapField) {
|
||
|
upb_Arena* source_arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* msg =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena);
|
||
|
ASSERT_TRUE(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_int32_double_set(
|
||
|
msg, 12, 1200.5, source_arena));
|
||
|
ASSERT_TRUE(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_string_set(
|
||
|
msg, upb_StringView_FromString("key1"),
|
||
|
upb_StringView_FromString("value1"), source_arena));
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage* nested =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_new(
|
||
|
source_arena);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(
|
||
|
nested, kTestNestedInt32);
|
||
|
ASSERT_TRUE(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_nested_message_set(
|
||
|
msg, upb_StringView_FromString("nestedkey1"), nested, source_arena));
|
||
|
|
||
|
upb_Arena* arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2* clone =
|
||
|
(protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_DeepClone(
|
||
|
msg, &protobuf_test_messages_proto2_TestAllTypesProto2_msg_init,
|
||
|
arena);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(nested,
|
||
|
0);
|
||
|
upb_Arena_Free(source_arena);
|
||
|
size_t iter = kUpb_Map_Begin;
|
||
|
// Test map<int32, int32>.
|
||
|
const protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry*
|
||
|
int32_double_entry =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_int32_double_next(
|
||
|
clone, &iter);
|
||
|
ASSERT_NE(int32_double_entry, nullptr);
|
||
|
EXPECT_EQ(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry_key(
|
||
|
int32_double_entry),
|
||
|
12);
|
||
|
EXPECT_EQ(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry_value(
|
||
|
int32_double_entry),
|
||
|
1200.5);
|
||
|
// Test map<string, string>.
|
||
|
iter = kUpb_Map_Begin;
|
||
|
const protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry*
|
||
|
string_string_entry =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_string_next(
|
||
|
clone, &iter);
|
||
|
ASSERT_NE(string_string_entry, nullptr);
|
||
|
EXPECT_TRUE(upb_StringView_IsEqual(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry_key(
|
||
|
string_string_entry),
|
||
|
upb_StringView_FromString("key1")));
|
||
|
EXPECT_TRUE(upb_StringView_IsEqual(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry_value(
|
||
|
string_string_entry),
|
||
|
upb_StringView_FromString("value1")));
|
||
|
// Test map<string, NestedMessage>.
|
||
|
iter = kUpb_Map_Begin;
|
||
|
const protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry*
|
||
|
nested_message_entry =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_nested_message_next(
|
||
|
clone, &iter);
|
||
|
ASSERT_NE(nested_message_entry, nullptr);
|
||
|
EXPECT_TRUE(upb_StringView_IsEqual(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry_key(
|
||
|
nested_message_entry),
|
||
|
upb_StringView_FromString("nestedkey1")));
|
||
|
const protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage*
|
||
|
cloned_nested =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry_value(
|
||
|
nested_message_entry);
|
||
|
ASSERT_NE(cloned_nested, nullptr);
|
||
|
EXPECT_EQ(protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_a(
|
||
|
cloned_nested),
|
||
|
kTestNestedInt32);
|
||
|
upb_Arena_Free(arena);
|
||
|
}
|
||
|
|
||
|
TEST(GeneratedCode, DeepCloneMessageExtensions) {
|
||
|
// Alloc and fill in test message with extension.
|
||
|
upb_Arena* source_arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect* msg =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect_new(
|
||
|
source_arena);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1*
|
||
|
ext1 =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_new(
|
||
|
source_arena);
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_set_str(
|
||
|
ext1, upb_StringView_FromString(kTestStr1));
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_set_message_set_extension(
|
||
|
msg, ext1, source_arena);
|
||
|
// Create clone.
|
||
|
upb_Arena* arena = upb_Arena_New();
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect* clone =
|
||
|
(protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect*)
|
||
|
upb_Message_DeepClone(
|
||
|
msg,
|
||
|
&protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrect_msg_init,
|
||
|
arena);
|
||
|
|
||
|
// Mutate original extension.
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_set_str(
|
||
|
ext1, upb_StringView_FromString(kTestStr2));
|
||
|
upb_Arena_Free(source_arena);
|
||
|
|
||
|
const protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1*
|
||
|
cloned_ext =
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_message_set_extension(
|
||
|
clone);
|
||
|
ASSERT_NE(cloned_ext, nullptr);
|
||
|
EXPECT_TRUE(upb_StringView_IsEqual(
|
||
|
protobuf_test_messages_proto2_TestAllTypesProto2_MessageSetCorrectExtension1_str(
|
||
|
cloned_ext),
|
||
|
upb_StringView_FromString(kTestStr1)));
|
||
|
upb_Arena_Free(arena);
|
||
|
}
|
||
|
} // namespace
|