Protobuf: removed secondary constructors and private setters (as features, which are not supported yet by translator)

This commit is contained in:
dsavvinov
2016-08-09 17:08:35 +03:00
parent 5586bebc79
commit f493ace24f
7 changed files with 55 additions and 46 deletions
@@ -7,6 +7,7 @@
#include "kotlin_enum_generator.h"
#include "kotlin_field_generator.h"
#include "kotlin_name_resolver.h"
#include "UnreachableStateException.h"
#include <algorithm>
namespace google {
@@ -34,9 +35,6 @@ void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
// Generate construction routines
generateInitSection(printer);
printer->Print("\n");
generateConstructor(printer, isBuilder);
printer->Print("\n");
// enum declarations and nested classes declarations only for fair classes
if (!isBuilder) {
@@ -106,15 +104,15 @@ ClassGenerator::ClassGenerator(Descriptor const *descriptor, NameResolver * name
int nested_types_count = descriptor->nested_type_count();
for (int i = 0; i < nested_types_count; ++i) {
Descriptor const * nestedClassDescriptor = descriptor->nested_type(i);
nameResolver->addClass(nestedClassDescriptor->name(), getFullType());
classesDeclarations.push_back(new ClassGenerator(nestedClassDescriptor, nameResolver));
nameResolver->addClass(nestedClassDescriptor->name(), getFullType(), classesDeclarations.back());
}
int enums_declarations_count = descriptor->enum_type_count();
for (int i = 0; i < enums_declarations_count; ++i) {
EnumDescriptor const * nestedEnumDescriptor = descriptor->enum_type(i);
nameResolver->addClass(nestedEnumDescriptor->name(), getFullType());
enumsDeclaraions.push_back(new EnumGenerator(nestedEnumDescriptor, nameResolver));
nameResolver->addClass(nestedEnumDescriptor->name(), getFullType(), /* classGenerator = */ nullptr);
}
/**
@@ -185,8 +183,9 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
printer->Indent();
vars["builderName"] = getBuilderFullType();
printer->Print(vars, "val builder = $builderName$()\n");
printer->Print("mergeWith(builder.parseFromWithSize(input, expectedSize).build())");
vars["initValue"] = getBuilderInitValue();
printer->Print(vars, "val builder = $initValue$\n");
printer->Print("mergeWith(builder.parseFromWithSize(input, expectedSize).build())\n");
printer->Outdent();
printer->Print("}\n");
@@ -197,8 +196,8 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
printer->Indent();
vars["builderName"] = getBuilderFullType();
printer->Print(vars, "val builder = $builderName$()\n");
printer->Print("mergeWith(builder.parseFrom(input).build())");
printer->Print(vars, "val builder = $initValue$\n");
printer->Print("mergeWith(builder.parseFrom(input).build())\n");
printer->Outdent();
printer->Print("}\n");
@@ -221,7 +220,7 @@ void ClassGenerator::generateWriteToMethod(io::Printer *printer) const {
printer->Print("}\n");
}
void ClassGenerator::generateConstructor(io::Printer * printer, bool isBuilder) const {
void ClassGenerator::generateHeader(io::Printer * printer, bool isBuilder) const {
// build list of arguments like 'field1: Type1, field2: Type2, ... '
string argumentList = "";
for (int i = 0; i < properties.size(); ++i) {
@@ -231,35 +230,12 @@ void ClassGenerator::generateConstructor(io::Printer * printer, bool isBuilder)
}
}
map <string, string> vars;
vars["name"] = isBuilder ? getBuidlerSimpleType() : getSimpleType();
vars["private"] = isBuilder ? "" : "private ";
vars["arguments"] = argumentList;
printer->Print(vars, "$private$constructor ($arguments$) : this() {\n");
printer->Indent();
for (int i = 0; i < properties.size(); ++i) {
map <string, string> vars;
vars["name"] = properties[i]->simpleName;
vars["initVal"] = properties[i]->getInitValue();
printer->Print(vars,
"this.$name$ = $name$"
"\n"
);
}
printer->Outdent();
printer->Print("}\n");
}
void ClassGenerator::generateHeader(io::Printer * printer, bool isBuilder) const {
map<string, string> vars;
vars["name"] = isBuilder? getBuidlerSimpleType() : getSimpleType();
vars["maybePrivate"] = isBuilder? "" : " private";
vars["args"] = argumentList;
printer->Print(vars,
"class $name$$maybePrivate$ constructor () {"
"class $name$$maybePrivate$ constructor ($args$) {"
"\n"
);
}
@@ -294,7 +270,7 @@ void ClassGenerator::generateInitSection(io::Printer * printer) const {
vars["name"] = properties[i]->simpleName;
vars["initVal"] = properties[i]->getInitValue();
printer->Print(vars,
"this.$name$ = $initVal$"
"this.$name$ = $name$"
"\n"
);
}
@@ -441,6 +417,19 @@ string ClassGenerator::getBuidlerSimpleType() const {
return "Builder" + getSimpleType();
}
string ClassGenerator::getBuilderInitValue() const {
// build list of arguments like 'field1: Type1, field2: Type2, ... '
string argumentList = "";
for (int i = 0; i < properties.size(); ++i) {
argumentList += properties[i]->simpleName + " = " + properties[i]->getInitValue();
if (i + 1 != properties.size()) {
argumentList += ", ";
}
}
return getBuilderFullType() + "(" + argumentList + ")";
}
} // namespace kotlin
} // namespace compiler
@@ -27,6 +27,7 @@ public:
string getFullType() const;
string getBuidlerSimpleType() const;
string getBuilderFullType() const;
string getBuilderInitValue() const;
vector <FieldGenerator *> properties;
vector <ClassGenerator *> classesDeclarations;
@@ -46,7 +47,6 @@ private:
NameResolver * nameResolver;
void generateHeader (io::Printer * printer, bool isBuilder = false) const;
void generateConstructor (io::Printer * printer, bool isBuilder = false) const;
void generateBuilder (io::Printer * printer) const;
void generateBuildMethod (io::Printer * printer) const;
void generateInitSection (io::Printer * printer) const;
@@ -19,15 +19,29 @@ string FieldGenerator::getInitValue() const {
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
return getFullType() + "(0)";
}
if (getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
return getBuilderFullType() + "().build()";
ClassGenerator * cg = nameResolver->getClassGenerator(getSimpleType());
// build list of arguments like 'field1: Type1, field2: Type2, ... '
string argumentList = "";
for (int i = 0; i < cg->properties.size(); ++i) {
argumentList += cg->properties[i]->simpleName + " = " + cg->properties[i]->getInitValue();
if (i + 1 != cg->properties.size()) {
argumentList += ", ";
}
}
return getBuilderFullType() + "(" + argumentList + ").build()";
}
if (getProtoType() == FieldDescriptor::TYPE_ENUM) {
return getEnumFromIntConverter() + "(0)";
}
return name_resolving::protobufTypeToInitValue(getProtoType());
}
void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
map<string, string> vars;
vars["name"] = simpleName;
@@ -38,11 +52,6 @@ void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
printer->Print(vars, "var $name$ : $field$\n");
// make setter private
printer->Indent();
printer->Print("private set\n");
printer->Outdent();
// generate setter for builder
if (isBuilder) {
generateSetter(printer);
@@ -73,6 +73,7 @@ public:
*/
string getInitValue() const;
/* Return string, that is suitable as suffix for corresponding IO methods in ProtoKot runtime.
* Example: int64-field -> Int64 (readInt64() and writeInt64() methods exist in ProtoKot runtime)
*/
@@ -37,8 +37,8 @@ bool FileGenerator::Generate(const FileDescriptor *file, const string &parameter
for (int i = 0; i < topLevelMessagesCount; ++i) {
Descriptor const * descriptor = file->message_type(i);
// TODO: think about order of initialization and cross-branches calls. If we don't allow such things, everythign is ok atm
nameResolver->addClass(descriptor->name(), "");
ClassGenerator * cgen = new ClassGenerator(descriptor, nameResolver);
nameResolver->addClass(descriptor->name(), /* parentName = */ "", cgen);
classes.push_back(cgen);
}
@@ -199,9 +199,12 @@ string protobufTypeToKotlinWireType(FieldDescriptor::Type type) {
NameResolver::NameResolver() {
names = map<string, string>();
builders = map<string, string>();
generators = map<string, ClassGenerator *>();
}
void NameResolver::addClass(string simpleName, string parentName) {
void NameResolver::addClass(string simpleName, string parentName, ClassGenerator * classGenerator) {
generators[simpleName] = classGenerator;
if (parentName == "") {
names[simpleName] = simpleName;
builders[simpleName] = simpleName + ".Builder" + simpleName;
@@ -221,6 +224,10 @@ string NameResolver::getBuilderName(string classSimpleName) {
return builders[classSimpleName];
}
ClassGenerator * NameResolver::getClassGenerator(string simpleName) {
return generators[simpleName];
}
} // namespace kotlin
} // namespace compiler
} // namespace protobuf
@@ -9,6 +9,7 @@
#include <google/protobuf/descriptor.h>
#include <map>
#include "kotlin_field_generator.h"
#include "kotlin_class_generator.h"
namespace google {
namespace protobuf {
@@ -22,12 +23,14 @@ class NameResolver {
public:
NameResolver();
void addClass (string simpleName, string parentName);
void addClass (string simpleName, string parentName, ClassGenerator * classGenerator);
string getClassName (string simpleName);
string getBuilderName (string classSimpleName);
ClassGenerator * getClassGenerator (string simpleName);
private:
std::map <string, string> names;
std::map <string, string> builders;
std::map <string, ClassGenerator *> generators;
};
namespace name_resolving {