1 #include "google/protobuf/compiler/code_generator.h"
2 #include "google/protobuf/io/zero_copy_stream.h"
3 #include "google/protobuf/io/printer.h"
4 #include "google/protobuf/descriptor.h"
5 #include "google/protobuf/descriptor.pb.h"
6 #include "schema_proto2_to_proto3_util.h"
7
8 #include "google/protobuf/compiler/plugin.h"
9
10 using google::protobuf::FileDescriptorProto;
11 using google::protobuf::FileDescriptor;
12 using google::protobuf::DescriptorPool;
13 using google::protobuf::io::Printer;
14 using google::protobuf::util::SchemaGroupStripper;
15 using google::protobuf::util::EnumScrubber;
16
17 namespace google {
18 namespace protobuf {
19 namespace compiler {
20
21 namespace {
22
StripProto(string filename)23 string StripProto(string filename) {
24 if (filename.substr(filename.size() - 11) == ".protodevel") {
25 // .protodevel
26 return filename.substr(0, filename.size() - 11);
27 } else {
28 // .proto
29 return filename.substr(0, filename.size() - 6);
30 }
31 }
32
33 DescriptorPool new_pool_;
34
35 } // namespace
36
37 class GoGoProtoGenerator : public CodeGenerator {
38 public:
GenerateAll(const std::vector<const FileDescriptor * > & files,const string & parameter,GeneratorContext * context,string * error) const39 virtual bool GenerateAll(const std::vector<const FileDescriptor*>& files,
40 const string& parameter,
41 GeneratorContext* context,
42 string* error) const {
43 for (int i = 0; i < files.size(); i++) {
44 for (auto file : files) {
45 bool can_generate =
46 (new_pool_.FindFileByName(file->name()) == nullptr);
47 for (int j = 0; j < file->dependency_count(); j++) {
48 can_generate &= (new_pool_.FindFileByName(
49 file->dependency(j)->name()) != nullptr);
50 }
51 for (int j = 0; j < file->public_dependency_count(); j++) {
52 can_generate &= (new_pool_.FindFileByName(
53 file->public_dependency(j)->name()) != nullptr);
54 }
55 for (int j = 0; j < file->weak_dependency_count(); j++) {
56 can_generate &= (new_pool_.FindFileByName(
57 file->weak_dependency(j)->name()) != nullptr);
58 }
59 if (can_generate) {
60 Generate(file, parameter, context, error);
61 break;
62 }
63 }
64 }
65
66 return true;
67 }
68
Generate(const FileDescriptor * file,const string & parameter,GeneratorContext * context,string * error) const69 virtual bool Generate(const FileDescriptor* file,
70 const string& parameter,
71 GeneratorContext* context,
72 string* error) const {
73 FileDescriptorProto new_file;
74 file->CopyTo(&new_file);
75 SchemaGroupStripper::StripFile(file, &new_file);
76
77 EnumScrubber enum_scrubber;
78 enum_scrubber.ScrubFile(&new_file);
79
80 string filename = file->name();
81 string basename = StripProto(filename);
82
83 std::vector<std::pair<string,string>> option_pairs;
84 ParseGeneratorParameter(parameter, &option_pairs);
85
86 std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
87 context->Open(basename + ".proto"));
88 string content = new_pool_.BuildFile(new_file)->DebugString();
89 Printer printer(output.get(), '$');
90 printer.WriteRaw(content.c_str(), content.size());
91
92 return true;
93 }
94 };
95
96 } // namespace compiler
97 } // namespace protobuf
98 } // namespace google
99
main(int argc,char * argv[])100 int main(int argc, char* argv[]) {
101 google::protobuf::compiler::GoGoProtoGenerator generator;
102 return google::protobuf::compiler::PluginMain(argc, argv, &generator);
103 }
104