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