123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934 |
- #include <google/protobuf/compiler/code_generator.h>
- #include <google/protobuf/compiler/cpp/helpers.h>
- #include <google/protobuf/descriptor.h>
- #include <google/protobuf/descriptor.pb.h>
- #include <google/protobuf/io/printer.h>
- #include <google/protobuf/io/zero_copy_stream.h>
- #include "cpp_styleguide.h"
- #include <util/stream/output.h>
- namespace NProtobuf {
- namespace NCompiler {
- namespace NPlugins {
- using namespace google::protobuf;
- using namespace google::protobuf::compiler;
- using namespace google::protobuf::compiler::cpp;
- typedef std::map<TProtoStringType, TProtoStringType> TVariables;
- bool GenerateYaStyle(const FileDescriptor* fileDescriptor) {
- const auto& extension = fileDescriptor->FindExtensionByName("GenerateYaStyle");
- return extension;
- }
- bool GenerateYaStyle(const FieldDescriptor* descriptor) {
- const auto& fileDescriptor = descriptor->file();
- return GenerateYaStyle(fileDescriptor);
- }
- void SetCommonFieldVariables(const FieldDescriptor* descriptor, TVariables* variables) {
- const auto& name = descriptor->name();
- if (GenerateYaStyle(descriptor))
- (*variables)["rname"] = UnderscoresToCamelCase(name, true);
- else
- (*variables)["rname"] = name;
- (*variables)["name"] = FieldName(descriptor);
- }
- TProtoStringType HeaderFileName(const FileDescriptor* file) {
- TProtoStringType basename = compiler::StripProto(file->name());
- return basename.append(".pb.h");
- }
- TProtoStringType SourceFileName(const FileDescriptor* file) {
- TProtoStringType basename = compiler::StripProto(file->name());
- return basename.append(".pb.cc");
- }
- bool IsLiteRuntimeMessage(const Descriptor* desc) {
- return desc->file() != NULL && desc->file()->options().optimize_for() == google::protobuf::FileOptions::LITE_RUNTIME;
- }
- bool IsAutogeneratedNestedType(const Descriptor* desc) {
- return desc->options().map_entry();
- }
- class TFieldExtGenerator {
- public:
- TFieldExtGenerator(const FieldDescriptor* field)
- : Field_(field)
- {
- SetCommonFieldVariables(Field_, &Variables_);
- }
- virtual ~TFieldExtGenerator() {
- }
- virtual void GenerateAccessorDeclarations(io::Printer* printer) = 0;
- virtual void GenerateJSONPrinting(io::Printer* printer) = 0;
- protected:
- void GenerateRepeatedJSONPrinting(io::Printer* printer, const char* itemPrinter) {
- printer->Print("out << '[';\n");
- printer->Print("{\n");
- printer->Indent();
- printer->Print("const char* separator = \"\";\n");
- printer->Print(Variables_, "for (size_t _index = 0; _index < $rname$Size(); ++_index) {\n");
- printer->Indent();
- printer->Print("out << separator;\n");
- printer->Print(Variables_, itemPrinter);
- printer->Print(";\n");
- printer->Print("separator = \",\";\n");
- printer->Outdent();
- printer->Print("}\n");
- printer->Outdent();
- printer->Print("}\n");
- printer->Print("out << ']';\n");
- }
- protected:
- const FieldDescriptor* Field_;
- TVariables Variables_;
- };
- class TMessageFieldExtGenerator: public TFieldExtGenerator {
- public:
- TMessageFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = QualifiedClassName(Field_->message_type());
- printer->Print(Variables_,
- "inline const $type$& Get$rname$() const { return $name$(); }\n"
- "inline $type$* Mutable$rname$() { return mutable_$name$(); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "Get$rname$().PrintJSON(out);\n");
- }
- };
- class TMapFieldExtGenerator: public TFieldExtGenerator {
- public:
- TMapFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- , Key_(field->message_type()->FindFieldByName("key"))
- , Val_(field->message_type()->FindFieldByName("value"))
- {
- Variables_["key_cpp"] = PrimitiveTypeName(Key_->cpp_type());
- switch (Val_->cpp_type()) {
- case FieldDescriptor::CPPTYPE_MESSAGE:
- Variables_["val_cpp"] = QualifiedClassName(Val_->message_type());
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- Variables_["val_cpp"] = ClassName(Val_->enum_type(), true);
- break;
- default:
- Variables_["val_cpp"] = PrimitiveTypeName(Val_->cpp_type());
- }
- }
- void GenerateAccessorDeclarations(io::Printer* printer) {
- printer->Print(Variables_,
- "inline const ::google::protobuf::Map<$key_cpp$, $val_cpp$>& Get$rname$() const { return $name$(); }\n"
- "inline ::google::protobuf::Map<$key_cpp$, $val_cpp$>* Mutable$rname$() { return mutable_$name$(); }\n");
- }
- void GenerateKeyValuePrinting(io::Printer* printer, const char* scopeName, bool isKey) {
- const FieldDescriptor* desc = isKey ? Key_ : Val_;
- switch(desc->cpp_type()) {
- case FieldDescriptor::CPPTYPE_STRING:
- printer->Print(TString::Join("::google::protobuf::io::PrintJSONString(out, ", scopeName , ");\n").data());
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- printer->Print(TString::Join("out << int(", scopeName, ");\n").data());
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- printer->Print(TString::Join(scopeName, ".PrintJSON(out);\n").data());
- break;
- default:
- if (isKey) {
- printer->Print(TString::Join("out << '\"' << ", scopeName, " << '\"';\n").data());
- } else {
- printer->Print(TString::Join("out << ", scopeName, ";\n").data());
- }
- }
- }
- void GenerateJSONPrinting(io::Printer* printer) {
- printer->Print(Variables_,
- "out << '{';\n"
- "const ::google::protobuf::Map<$key_cpp$, $val_cpp$>& map = Get$rname$();\n"
- "for (auto it = map.begin(); it != map.end(); ++it) {\n"
- );
- printer->Indent();
- printer->Print("if (it != map.begin()) { out << ','; }\n");
- GenerateKeyValuePrinting(printer, "it->first", true);
- printer->Print("out << ':';\n");
- GenerateKeyValuePrinting(printer, "it->second", false);
- printer->Outdent();
- printer->Print("}\n");
- printer->Print("out << '}';\n");
- }
- private:
- const FieldDescriptor* Key_;
- const FieldDescriptor* Val_;
- };
- class TRepeatedMessageFieldExtGenerator: public TFieldExtGenerator {
- public:
- TRepeatedMessageFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = QualifiedClassName(Field_->message_type());
- printer->Print(Variables_,
- "inline const $type$& Get$rname$(size_t _index) const {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return $name$(int(_index)); }\n"
- "inline $type$* Mutable$rname$(size_t _index) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return mutable_$name$(int(_index)); }\n"
- "inline $type$* Add$rname$() { return add_$name$(); }\n"
- "inline const $type$& get_idx_$name$(int _index) const { return $name$(_index); }\n"
- "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " get_arr_$name$() const { return $name$(); }\n"
- "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " Get$rname$() const { return $name$(); }\n"
- "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
- " Mutable$rname$() { return mutable_$name$(); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(printer, "Get$rname$(_index).PrintJSON(out)");
- }
- };
- class TStringFieldExtGenerator: public TFieldExtGenerator {
- public:
- TStringFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["pointer_type"] = Field_->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
- if (Field_->options().ctype() != FieldOptions::STRING) {
- printer->Outdent();
- printer->Print(
- " private:\n"
- " // Hidden due to unknown ctype option.\n");
- printer->Indent();
- }
- printer->Print(Variables_,
- "inline const TProtoStringType& Get$rname$() const { return $name$(); }\n"
- "inline void Set$rname$(const TProtoStringType& value) { set_$name$(value); }\n"
- "inline void Set$rname$(TProtoStringType&& value) { set_$name$(std::move(value)); }\n"
- "inline void Set$rname$(const char* value) { set_$name$(value); }\n"
- "inline void Set$rname$(const $pointer_type$* value, size_t size) { set_$name$(value, size); }\n"
- "inline TProtoStringType* Mutable$rname$() { return mutable_$name$(); }\n");
- if (Field_->options().ctype() != FieldOptions::STRING) {
- printer->Outdent();
- printer->Print(" public:\n");
- printer->Indent();
- }
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "::google::protobuf::io::PrintJSONString(out, Get$rname$());\n");
- }
- };
- class TRepeatedStringFieldExtGenerator: public TFieldExtGenerator {
- public:
- TRepeatedStringFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["pointer_type"] = Field_->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
- if (Field_->options().ctype() != FieldOptions::STRING) {
- printer->Outdent();
- printer->Print(
- " private:\n"
- " // Hidden due to unknown ctype option.\n");
- printer->Indent();
- }
- printer->Print(Variables_,
- "inline const TProtoStringType& Get$rname$(size_t _index) const {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return $name$(_index); }\n"
- "inline TProtoStringType* Mutable$rname$(size_t _index) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return mutable_$name$(_index); }\n"
- "inline void Set$rname$(size_t _index, const TProtoStringType& value) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, value); }\n"
- "inline void Set$rname$(size_t _index, TProtoStringType&& value) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, std::move(value)); }\n"
- "inline void Set$rname$(size_t _index, const char* value) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, value); }\n"
- "inline void Set$rname$(size_t _index, const $pointer_type$* value, size_t size) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, value, size); }\n"
- "inline TProtoStringType* Add$rname$() { return add_$name$(); }\n"
- "inline void Add$rname$(const TProtoStringType& value) { add_$name$(value); }\n"
- "inline void Add$rname$(TProtoStringType&& value) { add_$name$(std::move(value)); }\n"
- "inline void Add$rname$(const char* value) { add_$name$(value); }\n"
- "inline void Add$rname$(const $pointer_type$* value, size_t size) { add_$name$(value, size); }\n"
- "inline const TProtoStringType& get_idx_$name$(int _index) const { return $name$(_index); }\n"
- "inline const ::google::protobuf::RepeatedPtrField<TProtoStringType>& get_arr_$name$() const"
- "{ return $name$(); }\n"
- "inline const ::google::protobuf::RepeatedPtrField<TProtoStringType>& Get$rname$() const"
- "{ return $name$(); }\n"
- "inline ::google::protobuf::RepeatedPtrField<TProtoStringType>* Mutable$rname$()"
- "{ return mutable_$name$(); }\n");
- if (Field_->options().ctype() != FieldOptions::STRING) {
- printer->Outdent();
- printer->Print(" public:\n");
- printer->Indent();
- }
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(
- printer,
- "::google::protobuf::io::PrintJSONString(out, Get$rname$(_index))"
- );
- }
- };
- class TEnumFieldExtGenerator: public TFieldExtGenerator {
- public:
- TEnumFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = ClassName(Field_->enum_type(), true);
- printer->Print(Variables_,
- "inline $type$ Get$rname$() const { return $name$(); }\n"
- "inline void Set$rname$($type$ value) { set_$name$(value); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "out << (int)Get$rname$();\n");
- }
- };
- class TRepeatedEnumFieldExtGenerator: public TFieldExtGenerator {
- public:
- TRepeatedEnumFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = ClassName(Field_->enum_type(), true);
- printer->Print(Variables_,
- "inline $type$ Get$rname$(size_t _index) const {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return $name$(_index); }\n"
- "inline void Set$rname$(size_t _index, $type$ value) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, value); }\n"
- "inline void Add$rname$($type$ value) { add_$name$(value); }\n"
- "inline $type$ get_idx_$name$(int _index) const {return $name$(_index); }\n"
- "inline const ::google::protobuf::RepeatedField<int>& get_arr_$name$() const { return $name$(); }\n"
- "inline const ::google::protobuf::RepeatedField<int>& Get$rname$() const { return $name$(); }\n"
- "inline ::google::protobuf::RepeatedField<int>* Mutable$rname$() { return mutable_$name$(); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(printer, "out << (int)Get$rname$(_index)");
- }
- };
- class TPrimitiveFieldExtGenerator: public TFieldExtGenerator {
- public:
- TPrimitiveFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = PrimitiveTypeName(Field_->cpp_type());
- printer->Print(Variables_,
- "inline $type$ Get$rname$() const { return $name$();}\n"
- "inline void Set$rname$($type$ value) { set_$name$(value); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "out << Get$rname$();\n");
- }
- };
- class TRepeatedPrimitiveFieldExtGenerator: public TFieldExtGenerator {
- public:
- TRepeatedPrimitiveFieldExtGenerator(const FieldDescriptor* field)
- : TFieldExtGenerator(field)
- {
- }
- void GenerateAccessorDeclarations(io::Printer* printer) override {
- Variables_["type"] = PrimitiveTypeName(Field_->cpp_type());
- printer->Print(Variables_,
- "inline $type$ Get$rname$(size_t _index) const {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); return $name$(_index); }\n"
- "inline void Set$rname$(size_t _index, $type$ value) {Y_ASSERT(_index < static_cast<size_t>(::Max<int>())); set_$name$(_index, value); }\n"
- "inline void Add$rname$($type$ value) { add_$name$(value); }\n"
- "inline $type$ get_idx_$name$(int _index) const { return $name$(_index); }\n"
- "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
- " get_arr_$name$() const { return $name$(); }\n"
- "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
- " Get$rname$() const { return $name$(); }\n"
- "inline ::google::protobuf::RepeatedField< $type$ >*\n"
- " Mutable$rname$() { return mutable_$name$(); }\n");
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(printer, "out << Get$rname$(_index)");
- }
- };
- class TBoolFieldExtGenerator: public TPrimitiveFieldExtGenerator {
- public:
- TBoolFieldExtGenerator(const FieldDescriptor* field)
- : TPrimitiveFieldExtGenerator(field)
- {
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "out << (Get$rname$() ? \"true\" : \"false\");\n");
- }
- };
- class TRepeatedBoolFieldExtGenerator: public TRepeatedPrimitiveFieldExtGenerator {
- public:
- TRepeatedBoolFieldExtGenerator(const FieldDescriptor* field)
- : TRepeatedPrimitiveFieldExtGenerator(field)
- {
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(printer, "out << (Get$rname$(_index) ? \"true\" : \"false\")");
- }
- };
- class TFloatFieldExtGenerator: public TPrimitiveFieldExtGenerator {
- public:
- TFloatFieldExtGenerator(const FieldDescriptor* field)
- : TPrimitiveFieldExtGenerator(field)
- {
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- printer->Print(Variables_, "out << double(Get$rname$());\n");
- }
- };
- class TRepeatedFloatFieldExtGenerator: public TRepeatedPrimitiveFieldExtGenerator {
- public:
- TRepeatedFloatFieldExtGenerator(const FieldDescriptor* field)
- : TRepeatedPrimitiveFieldExtGenerator(field)
- {
- }
- void GenerateJSONPrinting(io::Printer* printer) override {
- GenerateRepeatedJSONPrinting(printer, "out << double(Get$rname$(_index))");
- }
- };
- // borrowed mostly from protobuf/compiler/cpp/cpp_extension.cc
- class TExtensionGenerator {
- public:
- TExtensionGenerator(const FieldDescriptor* descriptor)
- : Descriptor_(descriptor)
- {
- if (Descriptor_->is_repeated()) {
- type_traits_ = "Repeated";
- }
- TProtoStringType clsName;
- switch (Descriptor_->cpp_type()) {
- case FieldDescriptor::CPPTYPE_ENUM:
- type_traits_.append("EnumTypeTraits< ");
- clsName = ClassName(Descriptor_->enum_type(), true);
- type_traits_.append(clsName);
- type_traits_.append(", ");
- type_traits_.append(clsName);
- type_traits_.append("_IsValid>");
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- type_traits_.append("StringTypeTraits");
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- type_traits_.append("MessageTypeTraits< ");
- type_traits_.append(ClassName(Descriptor_->message_type(), true));
- type_traits_.append(" >");
- break;
- default:
- type_traits_.append("PrimitiveTypeTraits< ");
- type_traits_.append(PrimitiveTypeName(Descriptor_->cpp_type()));
- type_traits_.append(" >");
- break;
- }
- }
- void GenerateDeclaration(io::Printer* printer) const
- {
- TVariables vars;
- vars["extendee" ] = ClassName(Descriptor_->containing_type(), true);
- vars["type_traits" ] = type_traits_;
- vars["name" ] = Descriptor_->name();
- vars["field_type" ] = std::to_string(static_cast<int>(Descriptor_->type()));
- vars["packed" ] = Descriptor_->options().packed() ? "true" : "false";
- printer->Print(vars,
- "typedef ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
- " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
- " Td$name$;\n"
- );
- }
- private:
- const FieldDescriptor* Descriptor_;
- TProtoStringType type_traits_;
- };
- class TOneofGenerator {
- public:
- TOneofGenerator(const OneofDescriptor* Descriptor_)
- : Descriptor_(Descriptor_)
- {
- Variables_["camel_oneof_name"] = UnderscoresToCamelCase(Descriptor_->name(), true);
- Variables_["rname"] = Descriptor_->name();
- }
- void GenerateDeclarations(io::Printer* printer) const {
- printer->Print(Variables_, "$camel_oneof_name$Case Get$rname$Case() const { return $rname$_case(); }\n");
- printer->Print(Variables_, "void Clear$rname$() { clear_$rname$(); }\n");
- if (Descriptor_->name() != UnderscoresToCamelCase(Descriptor_->name(), true)) {
- printer->Print(Variables_, "$camel_oneof_name$Case Get$camel_oneof_name$Case() const { return $rname$_case(); }\n");
- printer->Print(Variables_, "void Clear$camel_oneof_name$() { clear_$rname$(); }\n");
- }
- }
- private:
- const OneofDescriptor* Descriptor_;
- TVariables Variables_;
- };
- TFieldExtGenerator* MakeGenerator(const FieldDescriptor* field) {
- if (field->is_repeated()) {
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (field->is_map()) {
- return new TMapFieldExtGenerator(field);
- }
- return new TRepeatedMessageFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_BOOL:
- return new TRepeatedBoolFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_FLOAT:
- return new TRepeatedFloatFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: // RepeatedStringFieldExtGenerator handles unknown ctypes.
- case FieldOptions::STRING:
- return new TRepeatedStringFieldExtGenerator(field);
- }
- case FieldDescriptor::CPPTYPE_ENUM:
- return new TRepeatedEnumFieldExtGenerator(field);
- default:
- return new TRepeatedPrimitiveFieldExtGenerator(field);
- }
- } else {
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_MESSAGE:
- return new TMessageFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_BOOL:
- return new TBoolFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_FLOAT:
- return new TFloatFieldExtGenerator(field);
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: // StringFieldGenerator handles unknown ctypes.
- case FieldOptions::STRING:
- return new TStringFieldExtGenerator(field);
- }
- case FieldDescriptor::CPPTYPE_ENUM:
- return new TEnumFieldExtGenerator(field);
- default:
- return new TPrimitiveFieldExtGenerator(field);
- }
- }
- }
- class TMessageExtGenerator {
- public:
- TMessageExtGenerator(const Descriptor* descriptor, OutputDirectory* outputDirectory)
- : Descriptor_(descriptor)
- , Classname_(ClassName(descriptor, false))
- , OutputDirectory_(outputDirectory)
- {
- for (int i = 0; i < descriptor->nested_type_count(); i++) {
- if (!IsAutogeneratedNestedType(descriptor->nested_type(i))) {
- NestedGenerators_.emplace_back(descriptor->nested_type(i), OutputDirectory_);
- }
- }
- FieldGenerators_.reserve(descriptor->field_count());
- for (int i = 0; i < descriptor->field_count(); i++) {
- FieldGenerators_.emplace_back(MakeGenerator(descriptor->field(i)));
- }
- ExtensionGenerators_.reserve(descriptor->extension_count());
- for (int i = 0; i < descriptor->extension_count(); i++) {
- ExtensionGenerators_.emplace_back(descriptor->extension(i));
- }
- OneofGenerators_.reserve(descriptor->real_oneof_decl_count());
- for (int i = 0; i < descriptor->real_oneof_decl_count(); i++) {
- OneofGenerators_.emplace_back(descriptor->oneof_decl(i));
- }
- }
- void GenerateClassDefinitionExtension() {
- GenerateSaveLoadImplementation();
- GenerateJSONImplementation();
- for (auto& nestedGenerator: NestedGenerators_) {
- nestedGenerator.GenerateClassDefinitionExtension();
- }
- }
- void GenerateDebugOutputExtension() {
- GenerateDebugOutput();
- for (auto& nestedGenerator: NestedGenerators_) {
- nestedGenerator.GenerateDebugOutputExtension();
- }
- }
- void GenerateTypedefOutputExtension(bool nested) {
- GenerateTypedefOutput(nested);
- for (auto& nestedGenerator: NestedGenerators_) {
- nestedGenerator.GenerateTypedefOutputExtension(true);
- }
- }
- void GenerateClassExtension() {
- GenerateDebugStringImplementation();
- for (auto& nestedGenerator: NestedGenerators_) {
- nestedGenerator.GenerateClassExtension();
- }
- }
- void GenerateDeclarations() {
- GenerateFieldAccessorDeclarations();
- for (auto& nestedGenerator: NestedGenerators_) {
- nestedGenerator.GenerateDeclarations();
- }
- }
- void GenerateDefinitions() {
- GenerateClassExtension();
- GenerateDebugOutputExtension();
- GenerateClassDefinitionExtension();
- }
- private:
- void GenerateFieldAccessorDeclarations() {
- TProtoStringType fileName = HeaderFileName(Descriptor_->file());
- TProtoStringType scope = "class_scope:" + Descriptor_->full_name();
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- printer.Print("// Yandex cpp-styleguide extension\n");
- for (int i = 0; i < Descriptor_->field_count(); i++) {
- const FieldDescriptor* field = Descriptor_->field(i);
- TVariables vars;
- SetCommonFieldVariables(field, &vars);
- if (field->is_repeated()) {
- printer.Print(vars,
- "inline size_t $rname$Size() const { return (size_t)$name$_size(); }\n");
- } else if (field->has_presence()) {
- printer.Print(vars,
- "inline bool Has$rname$() const { return has_$name$(); }\n");
- }
- printer.Print(vars, "inline void Clear$rname$() { clear_$name$(); }\n");
- // Generate type-specific accessor declarations.
- FieldGenerators_[i]->GenerateAccessorDeclarations(&printer);
- printer.Print("\n");
- }
- for (auto& extensionGenerator: ExtensionGenerators_) {
- extensionGenerator.GenerateDeclaration(&printer);
- }
- for (auto& oneofGenerator: OneofGenerators_) {
- oneofGenerator.GenerateDeclarations(&printer);
- }
- TVariables vars;
- vars["class"] = ClassName(Descriptor_, false);
- if (!IsLiteRuntimeMessage(Descriptor_)) {
- printer.Print("TProtoStringType ShortUtf8DebugString() const;\n");
- printer.Print("void PrintJSON(IOutputStream&) const override;\n");
- printer.Print(vars, "::google::protobuf::io::TAsJSON<$class$> AsJSON() const {\n");
- printer.Print(vars, " return ::google::protobuf::io::TAsJSON<$class$>(*this);\n");
- printer.Print("}\n");
- printer.Print("void Save(IOutputStream* output) const;\n");
- printer.Print("void Load(IInputStream* input);\n");
- }
- printer.Print("// End of Yandex-specific extension\n");
- }
- void GenerateSaveLoadImplementation() {
- TProtoStringType fileName = SourceFileName(Descriptor_->file());
- TProtoStringType scope = "namespace_scope";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- TVariables vars;
- vars["class"] = Classname_;
- if (!IsLiteRuntimeMessage(Descriptor_)) {
- printer.Print("// Yandex-specific extension\n");
- printer.Print(vars, "void $class$::Save(IOutputStream* output) const {\n");
- printer.Print(" ::Save(output, static_cast<const ::google::protobuf::Message&>(*this));\n");
- printer.Print("}\n");
- printer.Print(vars, "void $class$::Load(IInputStream* input) {\n");
- printer.Print(" ::Load(input, static_cast<::google::protobuf::Message&>(*this));\n");
- printer.Print("}\n");
- printer.Print("// End of Yandex-specific extension\n");
- }
- }
- void GenerateDebugStringImplementation() {
- TProtoStringType fileName = SourceFileName(Descriptor_->file());
- TProtoStringType scope = "namespace_scope";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- TVariables vars;
- vars["class"] = Classname_;
- if (!IsLiteRuntimeMessage(Descriptor_)) {
- printer.Print("// Yandex-specific extension\n");
- printer.Print(vars, "TProtoStringType $class$::ShortUtf8DebugString() const {\n");
- printer.Print(" return ::ShortUtf8DebugString(*this);\n");
- printer.Print("}\n");
- printer.Print("// End of Yandex-specific extension\n");
- }
- }
- void GenerateJSONImplementation() {
- if (IsLiteRuntimeMessage(Descriptor_)) {
- return;
- }
- TProtoStringType fileName = SourceFileName(Descriptor_->file());
- TProtoStringType scope = "namespace_scope";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- printer.Print("// Yandex JSON extension\n");
- TVariables vars;
- vars["class"] = ClassName(Descriptor_, true);
- printer.Print(vars, "inline void $class$::PrintJSON(IOutputStream& out) const {\n");
- printer.Indent();
- printer.Print("out << '{';\n");
- if (Descriptor_->field_count() > 0) {
- printer.Print("const char* sep = \"\";\n");
- }
- for (int i = 0; i < Descriptor_->field_count(); i++) {
- const FieldDescriptor* field = Descriptor_->field(i);
- TVariables vars;
- SetCommonFieldVariables(field, &vars);
- if (field->is_repeated()) {
- // map or repeated field in both proto3 and proto2 syntax
- printer.Print(vars, "if ($rname$Size() > 0) {\n");
- } else if (field->has_presence()) {
- // any optional or required field in proto2 syntax
- // message-field or any oneof field in proto3 syntax
- printer.Print(vars, "if (Has$rname$()) {\n");
- } else {
- // string, enum or primitive field in proto3 syntax
- printer.Print(vars, "if (Get$rname$()) {\n");
- }
- printer.Indent();
- printer.Print("out << sep;\n");
- printer.Print(vars, "out << \"\\\"$rname$\\\":\";\n");
- FieldGenerators_[i]->GenerateJSONPrinting(&printer);
- printer.Print(vars, "sep = \",\";\n");
- printer.Outdent();
- printer.Print("}\n");
- }
- printer.Print("out << '}';\n");
- printer.Outdent();
- printer.Print("}\n");
- printer.Print("// End of Yandex JSON extension\n");
- }
- void GenerateDebugOutput() {
- TProtoStringType fileName = SourceFileName(Descriptor_->file());
- TProtoStringType scope = "global_scope";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- if (!IsLiteRuntimeMessage(Descriptor_)) {
- printer.Print("// Yandex debug output extension\n");
- TVariables vars;
- vars["class"] = ClassName(Descriptor_, true);
- printer.Print("template<>\n");
- printer.Print(vars, "void Out< $class$>(IOutputStream& out, const $class$& msg) {\n");
- printer.Print(" out << \"{ \" << msg.ShortUtf8DebugString() << \" }\";\n");
- printer.Print("}\n");
- printer.Print("// End of Yandex debug output extension\n");
- }
- }
- void GenerateTypedefOutput(bool nested) {
- if (!GenerateYaStyle(Descriptor_->file()))
- return;
- TProtoStringType fileName = HeaderFileName(Descriptor_->file());
- TProtoStringType scope = nested ? "class_scope:" + Descriptor_->full_name().substr(0,
- Descriptor_->full_name().size() - Descriptor_->name().size() - 1)
- : "namespace_scope";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- TString name = Descriptor_->name();
- bool isOk = name.size() >= 2 && name[0] == 'T' && name[1] >= 'A' && name[1] <= 'Z';
- if (!isOk) {
- printer.Print("// Yandex typedef extension\n");
- TVariables vars;
- vars["class"] = name;
- vars["base_class"] = ClassName(Descriptor_, true);
- printer.Print(vars, "typedef $base_class$ T$class$;\n");
- printer.Print("// End of Yandex typedef extension\n");
- }
- }
- private:
- const Descriptor* Descriptor_;
- TProtoStringType Classname_;
- OutputDirectory* OutputDirectory_;
- std::vector<std::unique_ptr<TFieldExtGenerator>> FieldGenerators_;
- std::vector<TMessageExtGenerator> NestedGenerators_;
- std::vector<TExtensionGenerator> ExtensionGenerators_;
- std::vector<TOneofGenerator> OneofGenerators_;
- };
- class TFileExtGenerator {
- public:
- TFileExtGenerator(const FileDescriptor* file, OutputDirectory* output_directory)
- : File_(file)
- , OutputDirectory_(output_directory)
- {
- MessageGenerators_.reserve(file->message_type_count());
- for (int i = 0; i < file->message_type_count(); i++) {
- MessageGenerators_.emplace_back(file->message_type(i), OutputDirectory_);
- }
- }
- void GenerateHeaderExtensions() {
- GenerateHeaderIncludeExtensions();
- for (auto& messageGenerator: MessageGenerators_) {
- messageGenerator.GenerateTypedefOutputExtension(false);
- messageGenerator.GenerateDeclarations();
- }
- }
- void GenerateSourceExtensions() {
- GenerateSourceIncludeExtensions();
- for (auto& messageGenerator: MessageGenerators_) {
- messageGenerator.GenerateDefinitions();
- }
- }
- private:
- void GenerateSourceIncludeExtensions() {
- TProtoStringType fileName = SourceFileName(File_);
- TProtoStringType scope = "includes";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- printer.Print("#include <google/protobuf/messagext.h>\n");
- }
- void GenerateHeaderIncludeExtensions() {
- TProtoStringType fileName = HeaderFileName(File_);
- TProtoStringType scope = "includes";
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- OutputDirectory_->OpenForInsert(fileName, scope));
- io::Printer printer(output.get(), '$');
- printer.Print("#include <google/protobuf/json_util.h>\n");
- }
- private:
- const FileDescriptor* File_;
- OutputDirectory* OutputDirectory_;
- size_t MessageTypeCount_;
- std::vector<TMessageExtGenerator> MessageGenerators_;
- };
- bool TCppStyleGuideExtensionGenerator::Generate(const FileDescriptor* file,
- const TProtoStringType&,
- OutputDirectory* outputDirectory,
- TProtoStringType*) const {
- TFileExtGenerator fileGenerator(file, outputDirectory);
- // Generate header.
- fileGenerator.GenerateHeaderExtensions();
- // Generate cc file.
- fileGenerator.GenerateSourceExtensions();
- return true;
- }
- }
- }
- }
- int main(int argc, char* argv[]) {
- #ifdef _MSC_VER
- // Don't print a silly message or stick a modal dialog box in my face,
- // please.
- _set_abort_behavior(0, ~0);
- #endif // !_MSC_VER
- NProtobuf::NCompiler::NPlugins::TCppStyleGuideExtensionGenerator generator;
- return google::protobuf::compiler::PluginMain(argc, argv, &generator);
- }
|