blob: bfa6a5e54aa19a72f9f7ddf21049f9da662e0a84 [file] [log] [blame]
Austin Schuh40c16522018-10-28 20:27:54 -07001#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
10using google::protobuf::FileDescriptorProto;
11using google::protobuf::FileDescriptor;
12using google::protobuf::DescriptorPool;
13using google::protobuf::io::Printer;
14using google::protobuf::util::SchemaGroupStripper;
15using google::protobuf::util::SchemaAddZeroEnumValue;
16
17namespace google {
18namespace protobuf {
19namespace compiler {
20
21namespace {
22
23string 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
33DescriptorPool new_pool_;
34
35} // namespace
36
37class GoGoProtoGenerator : public CodeGenerator {
38 public:
39 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
69 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 SchemaAddZeroEnumValue 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
100int main(int argc, char* argv[]) {
101 google::protobuf::compiler::GoGoProtoGenerator generator;
102 return google::protobuf::compiler::PluginMain(argc, argv, &generator);
103}