• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 #ifndef PROTO_READER_PLUGIN_H
16 #define PROTO_READER_PLUGIN_H
17 #include <string>
18 #include <google/protobuf/compiler/code_generator.h>
19 #include <google/protobuf/compiler/plugin.h>
20 #include <google/protobuf/descriptor.h>
21 #include <google/protobuf/descriptor.pb.h>
22 #include <google/protobuf/io/printer.h>
23 #include <google/protobuf/io/zero_copy_stream.h>
24 
25 namespace SysTuning {
26 namespace ProtoReader {
27 using google::protobuf::Descriptor;
28 using google::protobuf::EnumDescriptor;
29 using google::protobuf::FieldDescriptor;
30 using google::protobuf::FileDescriptor;
31 using google::protobuf::compiler::GeneratorContext;
32 using google::protobuf::io::Printer;
33 using google::protobuf::io::ZeroCopyOutputStream;
34 
Uppercase(char c)35 inline char Uppercase(char c)
36 {
37     return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
38 }
39 
ToUppercase(const std::string & str)40 inline std::string ToUppercase(const std::string &str)
41 {
42     std::string string(str);
43     auto end = string.end();
44     for (auto c = string.begin(); c != end; ++c) {
45         *c = Uppercase(*c);
46     }
47     return string;
48 }
49 
50 class ProtoReaderGenerator {
51 public:
ProtoReaderGenerator(const FileDescriptor * file,Printer * printer)52     ProtoReaderGenerator(const FileDescriptor *file, Printer *printer) : fileDescriptor_(file), codePrinter_(printer) {}
53     bool WriteProtoReader();
54     void ParserNamespace();
55     void ParserDescriptors();
56     void ParserDependencies();
57     void GetPBReaderInfo();
58     void WriteBegin();
59     void WriteEnumDescriptor(const EnumDescriptor *enumeration);
60     void WriteDecoder(const Descriptor *descriptor);
61     void WriteEnum(const Descriptor *descriptor);
62     void WriteFunc(const Descriptor *descriptor, const int32_t maxFieldID);
63     void WriteEnd();
GetError()64     const std::string &GetError() const
65     {
66         return error_;
67     }
68 
69 public:
70     std::string wrapperNamespace_;
71 
72 private:
73     template <class T>
GetDescriptorName(const T * descriptor)74     inline std::string GetDescriptorName(const T *descriptor) const
75     {
76         if (!package_.empty()) {
77             auto strTmp = package_ + ".";
78             return descriptor->full_name().substr(descriptor->full_name().find(strTmp) + sizeof(strTmp));
79         } else {
80             return descriptor->full_name();
81         }
82     }
83     template <class T>
GetDescriptorClass(const T * descriptor)84     const std::string GetDescriptorClass(const T *descriptor)
85     {
86         std::string name = GetDescriptorName(descriptor);
87         size_t pos = name.find(".");
88         if (pos != std::string::npos) {
89             name = name.replace(name.find("."), 1, "_");
90         }
91         return name;
92     }
93     std::string GetFieldNumberConstant(const FieldDescriptor *field);
94 
95 private:
96     struct TypeDesc {
97         std::string toFunc;
98         std::string type;
99         std::string packedBufferType;
100     };
101     std::map<FieldDescriptor::Type, TypeDesc> fieldTypeDesc_ = {
102         {FieldDescriptor::TYPE_BOOL, {"ToBool", "bool", "kVarInt"}},
103         {FieldDescriptor::TYPE_SFIXED32, {"ToInt32", "int32_t", "kFixed32"}},
104         {FieldDescriptor::TYPE_SINT32, {"ToInt32", "int32_t", "kVarInt"}},
105         {FieldDescriptor::TYPE_INT32, {"ToInt32", "int32_t", "kVarInt"}},
106         {FieldDescriptor::TYPE_SFIXED64, {"ToInt64", "int64_t", "kFixed64"}},
107         {FieldDescriptor::TYPE_SINT64, {"ToInt64", "int64_t", "kVarInt"}},
108         {FieldDescriptor::TYPE_INT64, {"ToInt64", "int64_t", "kVarInt"}},
109         {FieldDescriptor::TYPE_FIXED32, {"ToUint32", "uint32_t", "kFixed32"}},
110         {FieldDescriptor::TYPE_UINT32, {"ToUint32", "uint32_t", "kVarInt"}},
111         {FieldDescriptor::TYPE_FIXED64, {"ToUint64", "uint64_t", "kFixed64"}},
112         {FieldDescriptor::TYPE_UINT64, {"ToUint64", "uint64_t", "kVarInt"}},
113         {FieldDescriptor::TYPE_FLOAT, {"ToFloat", "float", "kFixed32"}},
114         {FieldDescriptor::TYPE_DOUBLE, {"ToDouble", "double", "kFixed64"}},
115         {FieldDescriptor::TYPE_ENUM, {"ToInt32", "int32_t", "kVarInt"}},
116         {FieldDescriptor::TYPE_STRING, {"ToString", "CharsView", ""}},
117         {FieldDescriptor::TYPE_MESSAGE, {"ToBytes", "BytesView", ""}},
118         {FieldDescriptor::TYPE_BYTES, {"ToBytes", "BytesView", ""}},
119     };
120     const FileDescriptor *const fileDescriptor_;
121     Printer *const codePrinter_;
122     std::string error_;
123     std::string fileDefinded_;
124     std::string package_;
125     std::vector<std::string> vNamespaces_;
126     std::string fullNamespacePrefix_;
127     std::vector<const Descriptor *> vDescriptor_;
128     std::vector<const EnumDescriptor *> vEnumDescriptor_;
129     std::set<const FileDescriptor *> publicImports_;
130     std::set<const Descriptor *> referencedMessages_;
131     std::set<const EnumDescriptor *> referencedEnums_;
132 };
133 class ProtoReaderPlugin : public ::google::protobuf::compiler::CodeGenerator {
134 public:
ProtoReaderPlugin()135     explicit ProtoReaderPlugin(){};
~ProtoReaderPlugin()136     ~ProtoReaderPlugin() override{};
137     bool Generate(const FileDescriptor *file,
138                   const std::string &options,
139                   GeneratorContext *context,
140                   std::string *error) const override;
141 };
142 } // namespace ProtoReader
143 } // namespace SysTuning
144 #endif // PROTO_READER_PLUGIN_H
145