|  | @@ -0,0 +1,115 @@
 | 
	
		
			
				|  |  | +#include "google/protobuf/compiler/code_generator.h"
 | 
	
		
			
				|  |  | +#include "google/protobuf/io/zero_copy_stream.h"
 | 
	
		
			
				|  |  | +#include "google/protobuf/io/printer.h"
 | 
	
		
			
				|  |  | +#include "google/protobuf/descriptor.h"
 | 
	
		
			
				|  |  | +#include "google/protobuf/descriptor.pb.h"
 | 
	
		
			
				|  |  | +#include "schema_proto2_to_proto3_util.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include "google/protobuf/compiler/plugin.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +using google::protobuf::FileDescriptorProto;
 | 
	
		
			
				|  |  | +using google::protobuf::FileDescriptor;
 | 
	
		
			
				|  |  | +using google::protobuf::DescriptorPool;
 | 
	
		
			
				|  |  | +using google::protobuf::io::Printer;
 | 
	
		
			
				|  |  | +using google::protobuf::util::SchemaGroupStripper;
 | 
	
		
			
				|  |  | +using google::protobuf::util::EnumScrubber;
 | 
	
		
			
				|  |  | +using google::protobuf::util::ExtensionStripper;
 | 
	
		
			
				|  |  | +using google::protobuf::util::FieldScrubber;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +namespace google {
 | 
	
		
			
				|  |  | +namespace protobuf {
 | 
	
		
			
				|  |  | +namespace compiler {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +namespace {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +string StripProto(string filename) {
 | 
	
		
			
				|  |  | +  return filename.substr(0, filename.rfind(".proto"));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +DescriptorPool* GetPool() {
 | 
	
		
			
				|  |  | +  static DescriptorPool *pool = new DescriptorPool();
 | 
	
		
			
				|  |  | +  return pool;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}  // namespace
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class Proto2ToProto3Generator final : public CodeGenerator {
 | 
	
		
			
				|  |  | + public:
 | 
	
		
			
				|  |  | +  bool GenerateAll(const std::vector<const FileDescriptor*>& files,
 | 
	
		
			
				|  |  | +                           const string& parameter,
 | 
	
		
			
				|  |  | +                           GeneratorContext* context,
 | 
	
		
			
				|  |  | +                           string* error) const {
 | 
	
		
			
				|  |  | +    for (int i = 0; i < files.size(); i++) {
 | 
	
		
			
				|  |  | +      for (auto file : files) {
 | 
	
		
			
				|  |  | +        if (CanGenerate(file)) {
 | 
	
		
			
				|  |  | +          Generate(file, parameter, context, error);
 | 
	
		
			
				|  |  | +          break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  bool Generate(const FileDescriptor* file,
 | 
	
		
			
				|  |  | +                        const string& parameter,
 | 
	
		
			
				|  |  | +                        GeneratorContext* context,
 | 
	
		
			
				|  |  | +                        string* error) const {
 | 
	
		
			
				|  |  | +    FileDescriptorProto new_file;
 | 
	
		
			
				|  |  | +    file->CopyTo(&new_file);
 | 
	
		
			
				|  |  | +    SchemaGroupStripper::StripFile(file, &new_file);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    EnumScrubber enum_scrubber;
 | 
	
		
			
				|  |  | +    enum_scrubber.ScrubFile(&new_file);
 | 
	
		
			
				|  |  | +    ExtensionStripper::StripFile(&new_file);
 | 
	
		
			
				|  |  | +    FieldScrubber::ScrubFile(&new_file);
 | 
	
		
			
				|  |  | +    new_file.set_syntax("proto3");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    string filename = file->name();
 | 
	
		
			
				|  |  | +    string basename = StripProto(filename);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::vector<std::pair<string,string>> option_pairs;
 | 
	
		
			
				|  |  | +    ParseGeneratorParameter(parameter, &option_pairs);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
 | 
	
		
			
				|  |  | +        context->Open(basename + ".proto"));
 | 
	
		
			
				|  |  | +    string content = GetPool()->BuildFile(new_file)->DebugString();
 | 
	
		
			
				|  |  | +    Printer printer(output.get(), '$');
 | 
	
		
			
				|  |  | +    printer.WriteRaw(content.c_str(), content.size());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | + private:
 | 
	
		
			
				|  |  | +  bool CanGenerate(const FileDescriptor* file) const {
 | 
	
		
			
				|  |  | +    if (GetPool()->FindFileByName(file->name()) != nullptr) {
 | 
	
		
			
				|  |  | +      return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    for (int j = 0; j < file->dependency_count(); j++) {
 | 
	
		
			
				|  |  | +      if (GetPool()->FindFileByName(file->dependency(j)->name()) == nullptr) {
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    for (int j = 0; j < file->public_dependency_count(); j++) {
 | 
	
		
			
				|  |  | +      if (GetPool()->FindFileByName(
 | 
	
		
			
				|  |  | +          file->public_dependency(j)->name()) == nullptr) {
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    for (int j = 0; j < file->weak_dependency_count(); j++) {
 | 
	
		
			
				|  |  | +      if (GetPool()->FindFileByName(
 | 
	
		
			
				|  |  | +          file->weak_dependency(j)->name()) == nullptr) {
 | 
	
		
			
				|  |  | +        return false;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}  // namespace compiler
 | 
	
		
			
				|  |  | +}  // namespace protobuf
 | 
	
		
			
				|  |  | +}  // namespace google
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int main(int argc, char* argv[]) {
 | 
	
		
			
				|  |  | +  google::protobuf::compiler::Proto2ToProto3Generator generator;
 | 
	
		
			
				|  |  | +  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
 | 
	
		
			
				|  |  | +}
 |