xref: /aosp_15_r20/external/grpc-grpc/third_party/upb/upb/mini_descriptor/internal/encode.hpp (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef UPB_MINI_TABLE_ENCODE_INTERNAL_HPP_
9 #define UPB_MINI_TABLE_ENCODE_INTERNAL_HPP_
10 
11 #include <string>
12 
13 #include "upb/base/internal/log2.h"
14 #include "upb/mini_descriptor/internal/encode.h"
15 
16 namespace upb {
17 
18 class MtDataEncoder {
19  public:
MtDataEncoder()20   MtDataEncoder() : appender_(&encoder_) {}
21 
StartMessage(uint64_t msg_mod)22   bool StartMessage(uint64_t msg_mod) {
23     return appender_([this, msg_mod](char* buf) {
24       return upb_MtDataEncoder_StartMessage(&encoder_, buf, msg_mod);
25     });
26   }
27 
PutField(upb_FieldType type,uint32_t field_num,uint64_t field_mod)28   bool PutField(upb_FieldType type, uint32_t field_num, uint64_t field_mod) {
29     return appender_([this, type, field_num, field_mod](char* buf) {
30       return upb_MtDataEncoder_PutField(&encoder_, buf, type, field_num,
31                                         field_mod);
32     });
33   }
34 
StartOneof()35   bool StartOneof() {
36     return appender_([this](char* buf) {
37       return upb_MtDataEncoder_StartOneof(&encoder_, buf);
38     });
39   }
40 
PutOneofField(uint32_t field_num)41   bool PutOneofField(uint32_t field_num) {
42     return appender_([this, field_num](char* buf) {
43       return upb_MtDataEncoder_PutOneofField(&encoder_, buf, field_num);
44     });
45   }
46 
StartEnum()47   bool StartEnum() {
48     return appender_([this](char* buf) {
49       return upb_MtDataEncoder_StartEnum(&encoder_, buf);
50     });
51   }
52 
PutEnumValue(uint32_t enum_value)53   bool PutEnumValue(uint32_t enum_value) {
54     return appender_([this, enum_value](char* buf) {
55       return upb_MtDataEncoder_PutEnumValue(&encoder_, buf, enum_value);
56     });
57   }
58 
EndEnum()59   bool EndEnum() {
60     return appender_([this](char* buf) {
61       return upb_MtDataEncoder_EndEnum(&encoder_, buf);
62     });
63   }
64 
EncodeExtension(upb_FieldType type,uint32_t field_num,uint64_t field_mod)65   bool EncodeExtension(upb_FieldType type, uint32_t field_num,
66                        uint64_t field_mod) {
67     return appender_([this, type, field_num, field_mod](char* buf) {
68       return upb_MtDataEncoder_EncodeExtension(&encoder_, buf, type, field_num,
69                                                field_mod);
70     });
71   }
72 
EncodeMap(upb_FieldType key_type,upb_FieldType val_type,uint64_t key_mod,uint64_t val_mod)73   bool EncodeMap(upb_FieldType key_type, upb_FieldType val_type,
74                  uint64_t key_mod, uint64_t val_mod) {
75     return appender_([this, key_type, val_type, key_mod, val_mod](char* buf) {
76       return upb_MtDataEncoder_EncodeMap(&encoder_, buf, key_type, val_type,
77                                          key_mod, val_mod);
78     });
79   }
80 
EncodeMessageSet()81   bool EncodeMessageSet() {
82     return appender_([this](char* buf) {
83       return upb_MtDataEncoder_EncodeMessageSet(&encoder_, buf);
84     });
85   }
86 
data() const87   const std::string& data() const { return appender_.data(); }
88 
89  private:
90   class StringAppender {
91    public:
StringAppender(upb_MtDataEncoder * e)92     StringAppender(upb_MtDataEncoder* e) { e->end = buf_ + sizeof(buf_); }
93 
94     template <class T>
operator ()(T && func)95     bool operator()(T&& func) {
96       char* end = func(buf_);
97       if (!end) return false;
98       // C++ does not guarantee that string has doubling growth behavior, but
99       // we need it to avoid O(n^2).
100       str_.reserve(upb_Log2CeilingSize(str_.size() + (end - buf_)));
101       str_.append(buf_, end - buf_);
102       return true;
103     }
104 
data() const105     const std::string& data() const { return str_; }
106 
107    private:
108     char buf_[kUpb_MtDataEncoder_MinSize];
109     std::string str_;
110   };
111 
112   upb_MtDataEncoder encoder_;
113   StringAppender appender_;
114 };
115 
116 }  // namespace upb
117 
118 #endif /* UPB_MINI_TABLE_ENCODE_INTERNAL_HPP_ */
119