xref: /aosp_15_r20/external/protobuf/benchmarks/util/protoc-gen-proto2_to_proto3.cc (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/compiler/code_generator.h"
2*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/io/zero_copy_stream.h"
3*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/io/printer.h"
4*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/descriptor.h"
5*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/descriptor.pb.h"
6*1b3f573fSAndroid Build Coastguard Worker #include "schema_proto2_to_proto3_util.h"
7*1b3f573fSAndroid Build Coastguard Worker 
8*1b3f573fSAndroid Build Coastguard Worker #include "google/protobuf/compiler/plugin.h"
9*1b3f573fSAndroid Build Coastguard Worker 
10*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::FileDescriptorProto;
11*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::FileDescriptor;
12*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::DescriptorPool;
13*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::io::Printer;
14*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::util::SchemaGroupStripper;
15*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::util::EnumScrubber;
16*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::util::ExtensionStripper;
17*1b3f573fSAndroid Build Coastguard Worker using google::protobuf::util::FieldScrubber;
18*1b3f573fSAndroid Build Coastguard Worker 
19*1b3f573fSAndroid Build Coastguard Worker namespace google {
20*1b3f573fSAndroid Build Coastguard Worker namespace protobuf {
21*1b3f573fSAndroid Build Coastguard Worker namespace compiler {
22*1b3f573fSAndroid Build Coastguard Worker 
23*1b3f573fSAndroid Build Coastguard Worker namespace {
24*1b3f573fSAndroid Build Coastguard Worker 
StripProto(string filename)25*1b3f573fSAndroid Build Coastguard Worker string StripProto(string filename) {
26*1b3f573fSAndroid Build Coastguard Worker   return filename.substr(0, filename.rfind(".proto"));
27*1b3f573fSAndroid Build Coastguard Worker }
28*1b3f573fSAndroid Build Coastguard Worker 
GetPool()29*1b3f573fSAndroid Build Coastguard Worker DescriptorPool* GetPool() {
30*1b3f573fSAndroid Build Coastguard Worker   static DescriptorPool *pool = new DescriptorPool();
31*1b3f573fSAndroid Build Coastguard Worker   return pool;
32*1b3f573fSAndroid Build Coastguard Worker }
33*1b3f573fSAndroid Build Coastguard Worker 
34*1b3f573fSAndroid Build Coastguard Worker }  // namespace
35*1b3f573fSAndroid Build Coastguard Worker 
36*1b3f573fSAndroid Build Coastguard Worker class Proto2ToProto3Generator final : public CodeGenerator {
37*1b3f573fSAndroid Build Coastguard Worker  public:
GenerateAll(const std::vector<const FileDescriptor * > & files,const string & parameter,GeneratorContext * context,string * error) const38*1b3f573fSAndroid Build Coastguard Worker   bool GenerateAll(const std::vector<const FileDescriptor*>& files,
39*1b3f573fSAndroid Build Coastguard Worker                            const string& parameter,
40*1b3f573fSAndroid Build Coastguard Worker                            GeneratorContext* context,
41*1b3f573fSAndroid Build Coastguard Worker                            string* error) const {
42*1b3f573fSAndroid Build Coastguard Worker     for (int i = 0; i < files.size(); i++) {
43*1b3f573fSAndroid Build Coastguard Worker       for (auto file : files) {
44*1b3f573fSAndroid Build Coastguard Worker         if (CanGenerate(file)) {
45*1b3f573fSAndroid Build Coastguard Worker           Generate(file, parameter, context, error);
46*1b3f573fSAndroid Build Coastguard Worker           break;
47*1b3f573fSAndroid Build Coastguard Worker         }
48*1b3f573fSAndroid Build Coastguard Worker       }
49*1b3f573fSAndroid Build Coastguard Worker     }
50*1b3f573fSAndroid Build Coastguard Worker 
51*1b3f573fSAndroid Build Coastguard Worker     return true;
52*1b3f573fSAndroid Build Coastguard Worker   }
53*1b3f573fSAndroid Build Coastguard Worker 
Generate(const FileDescriptor * file,const string & parameter,GeneratorContext * context,string * error) const54*1b3f573fSAndroid Build Coastguard Worker   bool Generate(const FileDescriptor* file,
55*1b3f573fSAndroid Build Coastguard Worker                         const string& parameter,
56*1b3f573fSAndroid Build Coastguard Worker                         GeneratorContext* context,
57*1b3f573fSAndroid Build Coastguard Worker                         string* error) const {
58*1b3f573fSAndroid Build Coastguard Worker     FileDescriptorProto new_file;
59*1b3f573fSAndroid Build Coastguard Worker     file->CopyTo(&new_file);
60*1b3f573fSAndroid Build Coastguard Worker     SchemaGroupStripper::StripFile(file, &new_file);
61*1b3f573fSAndroid Build Coastguard Worker 
62*1b3f573fSAndroid Build Coastguard Worker     EnumScrubber enum_scrubber;
63*1b3f573fSAndroid Build Coastguard Worker     enum_scrubber.ScrubFile(&new_file);
64*1b3f573fSAndroid Build Coastguard Worker     ExtensionStripper::StripFile(&new_file);
65*1b3f573fSAndroid Build Coastguard Worker     FieldScrubber::ScrubFile(&new_file);
66*1b3f573fSAndroid Build Coastguard Worker     new_file.set_syntax("proto3");
67*1b3f573fSAndroid Build Coastguard Worker 
68*1b3f573fSAndroid Build Coastguard Worker     string filename = file->name();
69*1b3f573fSAndroid Build Coastguard Worker     string basename = StripProto(filename);
70*1b3f573fSAndroid Build Coastguard Worker 
71*1b3f573fSAndroid Build Coastguard Worker     std::vector<std::pair<string,string>> option_pairs;
72*1b3f573fSAndroid Build Coastguard Worker     ParseGeneratorParameter(parameter, &option_pairs);
73*1b3f573fSAndroid Build Coastguard Worker 
74*1b3f573fSAndroid Build Coastguard Worker     std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
75*1b3f573fSAndroid Build Coastguard Worker         context->Open(basename + ".proto"));
76*1b3f573fSAndroid Build Coastguard Worker     string content = GetPool()->BuildFile(new_file)->DebugString();
77*1b3f573fSAndroid Build Coastguard Worker     Printer printer(output.get(), '$');
78*1b3f573fSAndroid Build Coastguard Worker     printer.WriteRaw(content.c_str(), content.size());
79*1b3f573fSAndroid Build Coastguard Worker 
80*1b3f573fSAndroid Build Coastguard Worker     return true;
81*1b3f573fSAndroid Build Coastguard Worker   }
82*1b3f573fSAndroid Build Coastguard Worker  private:
CanGenerate(const FileDescriptor * file) const83*1b3f573fSAndroid Build Coastguard Worker   bool CanGenerate(const FileDescriptor* file) const {
84*1b3f573fSAndroid Build Coastguard Worker     if (GetPool()->FindFileByName(file->name()) != nullptr) {
85*1b3f573fSAndroid Build Coastguard Worker       return false;
86*1b3f573fSAndroid Build Coastguard Worker     }
87*1b3f573fSAndroid Build Coastguard Worker     for (int j = 0; j < file->dependency_count(); j++) {
88*1b3f573fSAndroid Build Coastguard Worker       if (GetPool()->FindFileByName(file->dependency(j)->name()) == nullptr) {
89*1b3f573fSAndroid Build Coastguard Worker         return false;
90*1b3f573fSAndroid Build Coastguard Worker       }
91*1b3f573fSAndroid Build Coastguard Worker     }
92*1b3f573fSAndroid Build Coastguard Worker     for (int j = 0; j < file->public_dependency_count(); j++) {
93*1b3f573fSAndroid Build Coastguard Worker       if (GetPool()->FindFileByName(
94*1b3f573fSAndroid Build Coastguard Worker           file->public_dependency(j)->name()) == nullptr) {
95*1b3f573fSAndroid Build Coastguard Worker         return false;
96*1b3f573fSAndroid Build Coastguard Worker       }
97*1b3f573fSAndroid Build Coastguard Worker     }
98*1b3f573fSAndroid Build Coastguard Worker     for (int j = 0; j < file->weak_dependency_count(); j++) {
99*1b3f573fSAndroid Build Coastguard Worker       if (GetPool()->FindFileByName(
100*1b3f573fSAndroid Build Coastguard Worker           file->weak_dependency(j)->name()) == nullptr) {
101*1b3f573fSAndroid Build Coastguard Worker         return false;
102*1b3f573fSAndroid Build Coastguard Worker       }
103*1b3f573fSAndroid Build Coastguard Worker     }
104*1b3f573fSAndroid Build Coastguard Worker     return true;
105*1b3f573fSAndroid Build Coastguard Worker   }
106*1b3f573fSAndroid Build Coastguard Worker };
107*1b3f573fSAndroid Build Coastguard Worker 
108*1b3f573fSAndroid Build Coastguard Worker }  // namespace compiler
109*1b3f573fSAndroid Build Coastguard Worker }  // namespace protobuf
110*1b3f573fSAndroid Build Coastguard Worker }  // namespace google
111*1b3f573fSAndroid Build Coastguard Worker 
main(int argc,char * argv[])112*1b3f573fSAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
113*1b3f573fSAndroid Build Coastguard Worker   google::protobuf::compiler::Proto2ToProto3Generator generator;
114*1b3f573fSAndroid Build Coastguard Worker   return google::protobuf::compiler::PluginMain(argc, argv, &generator);
115*1b3f573fSAndroid Build Coastguard Worker }
116