/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  |  |  | 
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_  |