Skip to content

Commit ced36a4

Browse files
tholenstcopybara-github
authored andcommitted
Add a class TpbMessageDescriptor.
Tpb stands for "Tink ProtoBuf" and will prefix the helper classes for Tink protobuf parsing. PiperOrigin-RevId: 653994693 Change-Id: Ib9811c6140c44e54e0c092d4e127cb3a22e7ed7b
1 parent a2d15d5 commit ced36a4

5 files changed

+437
-0
lines changed

tink/internal/BUILD.bazel

+23
Original file line numberDiff line numberDiff line change
@@ -1367,3 +1367,26 @@ cc_library(
13671367
hdrs = ["dfsan_forwarders.h"],
13681368
deps = ["@com_google_absl//absl/base"],
13691369
)
1370+
1371+
cc_library(
1372+
name = "tpb_message_descriptor",
1373+
srcs = ["tpb_message_descriptor.cc"],
1374+
hdrs = ["tpb_message_descriptor.h"],
1375+
include_prefix = "tink/internal",
1376+
deps = [
1377+
"@com_google_absl//absl/container:btree",
1378+
"@com_google_absl//absl/status",
1379+
"@com_google_absl//absl/status:statusor",
1380+
"@com_google_absl//absl/strings",
1381+
],
1382+
)
1383+
1384+
cc_test(
1385+
name = "tpb_message_descriptor_test",
1386+
srcs = ["tpb_message_descriptor_test.cc"],
1387+
deps = [
1388+
":tpb_message_descriptor",
1389+
"//tink/util:test_matchers",
1390+
"@com_google_googletest//:gtest_main",
1391+
],
1392+
)

tink/internal/CMakeLists.txt

+22
Original file line numberDiff line numberDiff line change
@@ -1314,3 +1314,25 @@ tink_cc_test(
13141314
tink::util::statusor
13151315
tink::util::test_matchers
13161316
)
1317+
1318+
tink_cc_library(
1319+
NAME tpb_message_descriptor
1320+
SRCS
1321+
tpb_message_descriptor.cc
1322+
tpb_message_descriptor.h
1323+
DEPS
1324+
absl::btree
1325+
absl::status
1326+
absl::statusor
1327+
absl::strings
1328+
)
1329+
1330+
tink_cc_test(
1331+
NAME tpb_message_descriptor_test
1332+
SRCS
1333+
tpb_message_descriptor_test.cc
1334+
DEPS
1335+
tink::internal::tpb_message_descriptor
1336+
gmock
1337+
tink::util::test_matchers
1338+
)
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
///////////////////////////////////////////////////////////////////////////////
16+
17+
#include "tink/internal/tpb_message_descriptor.h"
18+
19+
#include <memory>
20+
#include <utility>
21+
22+
#include "absl/status/status.h"
23+
#include "absl/status/statusor.h"
24+
#include "absl/strings/str_cat.h"
25+
26+
namespace crypto {
27+
namespace tink {
28+
namespace internal {
29+
30+
absl::Status TpbMessageDescriptor::AddUint32(int tag) {
31+
if (!types_.emplace(tag, Type::kUint32).second) {
32+
return absl::InvalidArgumentError(
33+
absl::StrCat("Tag ", tag, " already exists"));
34+
}
35+
return absl::OkStatus();
36+
}
37+
38+
absl::Status TpbMessageDescriptor::AddBytes(int tag) {
39+
if (!types_.emplace(tag, Type::kBytes).second) {
40+
return absl::InvalidArgumentError(
41+
absl::StrCat("Tag ", tag, " already exists"));
42+
}
43+
return absl::OkStatus();
44+
}
45+
46+
absl::Status TpbMessageDescriptor::AddMessage(
47+
int tag, const TpbMessageDescriptor& descriptor) {
48+
if (!types_.emplace(tag, Type::kMessage).second) {
49+
return absl::InvalidArgumentError(
50+
absl::StrCat("Tag ", tag, " already exists"));
51+
}
52+
message_descriptors_[tag] =
53+
std::make_shared<TpbMessageDescriptor>(descriptor);
54+
return absl::OkStatus();
55+
}
56+
57+
const TpbMessageDescriptor* TpbMessageDescriptor::GetMessage(
58+
int tag) const {
59+
auto it = message_descriptors_.find(tag);
60+
if (it == message_descriptors_.end()) {
61+
return nullptr;
62+
}
63+
return it->second.get();
64+
}
65+
66+
absl::StatusOr<TpbMessageDescriptor::Type> TpbMessageDescriptor::GetType(
67+
int tag) const {
68+
auto it = types_.find(tag);
69+
if (it == types_.end()) {
70+
return absl::InvalidArgumentError(absl::StrCat("Tag ", tag, " not found"));
71+
}
72+
return it->second;
73+
}
74+
75+
bool operator==(const TpbMessageDescriptor& lhs,
76+
const TpbMessageDescriptor& rhs) {
77+
if (lhs.types_ != rhs.types_) return false;
78+
return lhs.message_descriptors_.size() == rhs.message_descriptors_.size() &&
79+
std::equal(lhs.message_descriptors_.begin(),
80+
lhs.message_descriptors_.end(),
81+
rhs.message_descriptors_.begin(), [](auto l, auto r) {
82+
return l.first == r.first && *l.second == *r.second;
83+
});
84+
}
85+
86+
bool operator!=(const TpbMessageDescriptor& lhs,
87+
const TpbMessageDescriptor& rhs) {
88+
return !(lhs == rhs);
89+
}
90+
91+
} // namespace internal
92+
} // namespace tink
93+
} // namespace crypto
+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
///////////////////////////////////////////////////////////////////////////////
16+
17+
#ifndef TINK_INTERNAL_TPB_MESSAGE_DESCRIPTOR_H_
18+
#define TINK_INTERNAL_TPB_MESSAGE_DESCRIPTOR_H_
19+
20+
#include <memory>
21+
22+
#include "absl/container/btree_map.h"
23+
#include "absl/status/status.h"
24+
#include "absl/status/statusor.h"
25+
26+
namespace crypto {
27+
namespace tink {
28+
namespace internal {
29+
30+
// A TinkProtoBuf message descriptor. This describes the format of a message.
31+
// (i.e., it describes what's usually in a .proto file).
32+
class TpbMessageDescriptor {
33+
public:
34+
TpbMessageDescriptor() = default;
35+
// Movable and copyable.
36+
TpbMessageDescriptor(const TpbMessageDescriptor&) = default;
37+
TpbMessageDescriptor(TpbMessageDescriptor&&) noexcept = default;
38+
TpbMessageDescriptor& operator=(const TpbMessageDescriptor&) = default;
39+
TpbMessageDescriptor& operator=(TpbMessageDescriptor&&) noexcept = default;
40+
41+
// The type of a field:
42+
// https://protobuf.dev/reference/protobuf/proto3-spec/#fields
43+
enum class Type { kUint32, kBytes, kMessage };
44+
45+
// Adds a uint32 field with the given tag.
46+
absl::Status AddUint32(int tag);
47+
48+
// Adds a bytes field with the given tag.
49+
absl::Status AddBytes(int tag);
50+
51+
// Adds a message field with the given tag.
52+
// Note: recursive messages are not supported.
53+
absl::Status AddMessage(int tag, const TpbMessageDescriptor& descriptor);
54+
const TpbMessageDescriptor* GetMessage(int tag) const;
55+
56+
// Returns the type of the field with the given tag.
57+
absl::StatusOr<Type> GetType(int tag) const;
58+
59+
friend bool operator==(const TpbMessageDescriptor& lhs,
60+
const TpbMessageDescriptor& rhs);
61+
friend bool operator!=(const TpbMessageDescriptor& lhs,
62+
const TpbMessageDescriptor& rhs);
63+
64+
private:
65+
absl::btree_map<int, Type> types_;
66+
// We cannot have a map <int, TpbMessageDescriptor> because
67+
// TpbMessageDescriptor is incomplete at this point. We hence use shared_ptr
68+
// instead (with unique_ptr we would have to manually write the copy
69+
// constructor of TpbMessageDescriptor).
70+
absl::btree_map<int, std::shared_ptr<TpbMessageDescriptor>>
71+
message_descriptors_;
72+
};
73+
74+
} // namespace internal
75+
} // namespace tink
76+
} // namespace crypto
77+
78+
#endif // TINK_INTERNAL_TPB_MESSAGE_DESCRIPTOR_H_

0 commit comments

Comments
 (0)