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