/src/abseil-cpp/absl/log/internal/structured_proto.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2024 The Abseil Authors. |
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 | | // https://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 | | // File: log/internal/structured_proto.h |
17 | | // ----------------------------------------------------------------------------- |
18 | | |
19 | | #ifndef ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_ |
20 | | #define ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_ |
21 | | |
22 | | #include <cstddef> |
23 | | #include <cstdint> |
24 | | |
25 | | #include "absl/base/config.h" |
26 | | #include "absl/log/internal/proto.h" |
27 | | #include "absl/types/span.h" |
28 | | #include "absl/types/variant.h" |
29 | | |
30 | | namespace absl { |
31 | | ABSL_NAMESPACE_BEGIN |
32 | | namespace log_internal { |
33 | | |
34 | | // Sum type holding a single valid protobuf field suitable for encoding. |
35 | | struct StructuredProtoField final { |
36 | | // Numeric type encoded with varint encoding: |
37 | | // https://protobuf.dev/programming-guides/encoding/#varints |
38 | | using Varint = absl::variant<uint64_t, int64_t, uint32_t, int32_t, bool>; |
39 | | |
40 | | // Fixed-length 64-bit integer encoding: |
41 | | // https://protobuf.dev/programming-guides/encoding/#non-varints |
42 | | using I64 = absl::variant<uint64_t, int64_t, double>; |
43 | | |
44 | | // Length-delimited record type (string, sub-message): |
45 | | // https://protobuf.dev/programming-guides/encoding/#length-types |
46 | | using LengthDelimited = absl::Span<const char>; |
47 | | |
48 | | // Fixed-length 32-bit integer encoding: |
49 | | // https://protobuf.dev/programming-guides/encoding/#non-varints |
50 | | using I32 = absl::variant<uint32_t, int32_t, float>; |
51 | | |
52 | | // Valid record type: |
53 | | // https://protobuf.dev/programming-guides/encoding/#structure |
54 | | using Value = absl::variant<Varint, I64, LengthDelimited, I32>; |
55 | | |
56 | | // Field number for the protobuf value. |
57 | | uint64_t field_number; |
58 | | |
59 | | // Value to encode. |
60 | | Value value; |
61 | | }; |
62 | | |
63 | | // Estimates the number of bytes needed to encode `field` using |
64 | | // protobuf encoding. |
65 | | // |
66 | | // The returned value might be larger than the actual number of bytes needed. |
67 | 0 | inline size_t BufferSizeForStructuredProtoField(StructuredProtoField field) { |
68 | | // Visitor to estimate the number of bytes of one of the types contained |
69 | | // inside `StructuredProtoField`. |
70 | 0 | struct BufferSizeVisitor final { |
71 | 0 | size_t operator()(StructuredProtoField::Varint /*unused*/) { |
72 | 0 | return BufferSizeFor(field_number, WireType::kVarint); |
73 | 0 | } |
74 | |
|
75 | 0 | size_t operator()(StructuredProtoField::I64 /*unused*/) { |
76 | 0 | return BufferSizeFor(field_number, WireType::k64Bit); |
77 | 0 | } |
78 | |
|
79 | 0 | size_t operator()(StructuredProtoField::LengthDelimited length_delimited) { |
80 | 0 | return BufferSizeFor(field_number, WireType::kLengthDelimited) + |
81 | 0 | length_delimited.size(); |
82 | 0 | } |
83 | |
|
84 | 0 | size_t operator()(StructuredProtoField::I32 /*unused*/) { |
85 | 0 | return BufferSizeFor(field_number, WireType::k32Bit); |
86 | 0 | } |
87 | |
|
88 | 0 | uint64_t field_number; |
89 | 0 | }; |
90 | |
|
91 | 0 | return absl::visit(BufferSizeVisitor{field.field_number}, field.value); |
92 | 0 | } |
93 | | |
94 | | // Encodes `field` into `buf` using protobuf encoding. |
95 | | // |
96 | | // On success, returns `true` and advances `buf` to the end of |
97 | | // the bytes consumed. |
98 | | // |
99 | | // On failure (if `buf` was too small), returns `false`. |
100 | | bool EncodeStructuredProtoField(StructuredProtoField field, |
101 | | absl::Span<char>& buf); |
102 | | |
103 | | } // namespace log_internal |
104 | | ABSL_NAMESPACE_END |
105 | | } // namespace absl |
106 | | |
107 | | #endif // ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_ |