104 lines
3.2 KiB
C++
104 lines
3.2 KiB
C++
|
#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;
|
||
|
|
||
|
namespace google {
|
||
|
namespace protobuf {
|
||
|
namespace compiler {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
string StripProto(string filename) {
|
||
|
if (filename.substr(filename.size() - 11) == ".protodevel") {
|
||
|
// .protodevel
|
||
|
return filename.substr(0, filename.size() - 11);
|
||
|
} else {
|
||
|
// .proto
|
||
|
return filename.substr(0, filename.size() - 6);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DescriptorPool new_pool_;
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
class GoGoProtoGenerator : public CodeGenerator {
|
||
|
public:
|
||
|
virtual 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) {
|
||
|
bool can_generate =
|
||
|
(new_pool_.FindFileByName(file->name()) == nullptr);
|
||
|
for (int j = 0; j < file->dependency_count(); j++) {
|
||
|
can_generate &= (new_pool_.FindFileByName(
|
||
|
file->dependency(j)->name()) != nullptr);
|
||
|
}
|
||
|
for (int j = 0; j < file->public_dependency_count(); j++) {
|
||
|
can_generate &= (new_pool_.FindFileByName(
|
||
|
file->public_dependency(j)->name()) != nullptr);
|
||
|
}
|
||
|
for (int j = 0; j < file->weak_dependency_count(); j++) {
|
||
|
can_generate &= (new_pool_.FindFileByName(
|
||
|
file->weak_dependency(j)->name()) != nullptr);
|
||
|
}
|
||
|
if (can_generate) {
|
||
|
Generate(file, parameter, context, error);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
virtual 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);
|
||
|
|
||
|
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 = new_pool_.BuildFile(new_file)->DebugString();
|
||
|
Printer printer(output.get(), '$');
|
||
|
printer.WriteRaw(content.c_str(), content.size());
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace compiler
|
||
|
} // namespace protobuf
|
||
|
} // namespace google
|
||
|
|
||
|
int main(int argc, char* argv[]) {
|
||
|
google::protobuf::compiler::GoGoProtoGenerator generator;
|
||
|
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
|
||
|
}
|