Protobuf: prettified generated code
This commit is contained in:
Binary file not shown.
+28
-19
@@ -21,31 +21,33 @@ void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
|
|||||||
generateHeader(printer, isBuilder);
|
generateHeader(printer, isBuilder);
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
|
|
||||||
/*
|
// Generate code for property declaration
|
||||||
* Field generator should know if it is generating code for builder
|
printer->Print("//========== Properties ===========\n");
|
||||||
* or for fair class to choose between 'val' and 'var'.
|
|
||||||
* Also note that fields should be declared before init section.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (FieldGenerator *gen: properties) {
|
for (FieldGenerator *gen: properties) {
|
||||||
gen->generateCode(printer, isBuilder);
|
gen->generateCode(printer, isBuilder);
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate field for errors code
|
// Generate field for errors code
|
||||||
printer->Print("\n");
|
printer->Print("var errorCode: Int = 0\n\n");
|
||||||
printer->Print("var errorCode: Int = 0\n");
|
|
||||||
|
|
||||||
printer->Print("\n");
|
|
||||||
generateInitSection(printer);
|
generateInitSection(printer);
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
|
|
||||||
// enum declarations and nested classes declarations only for fair classes
|
// enum declarations and nested classes declarations only for fair classes
|
||||||
if (!isBuilder) {
|
if (!isBuilder) {
|
||||||
|
if (enumsDeclaraions.size() > 0) {
|
||||||
|
printer->Print("//========== Nested enums declarations ===========\n");
|
||||||
|
}
|
||||||
for (EnumGenerator *gen: enumsDeclaraions) {
|
for (EnumGenerator *gen: enumsDeclaraions) {
|
||||||
gen->generateCode(printer);
|
gen->generateCode(printer);
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (classesDeclarations.size() > 0) {
|
||||||
|
printer->Print("//========== Nested classes declarations ===========\n");
|
||||||
|
}
|
||||||
for (ClassGenerator *gen: classesDeclarations) {
|
for (ClassGenerator *gen: classesDeclarations) {
|
||||||
gen->generateCode(printer);
|
gen->generateCode(printer);
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
@@ -53,30 +55,37 @@ void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write serialization methods only for fair classes, read methods only for Builders)
|
// write serialization methods only for fair classes, read methods only for Builders)
|
||||||
printer->Print("\n");
|
printer->Print("//========== Serialization methods ===========\n");
|
||||||
generateWriteToMethod(printer);
|
generateWriteToMethod(printer);
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
// builder, mergeFrom and only for fair classes
|
// builder, mergeFrom and only for fair classes
|
||||||
if (!isBuilder) {
|
if (!isBuilder) {
|
||||||
printer->Print("\n");
|
|
||||||
generateBuilder(printer);
|
|
||||||
|
|
||||||
printer->Print("\n");
|
|
||||||
generateMergeMethods(printer);
|
generateMergeMethods(printer);
|
||||||
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// build() and setters are only for builders
|
// build() and setters are only for builders
|
||||||
if (isBuilder) {
|
if (isBuilder) {
|
||||||
printer->Print("\n");
|
printer->Print("//========== Mutating methods ===========\n");
|
||||||
generateBuildMethod(printer);
|
generateBuildMethod(printer);
|
||||||
|
|
||||||
printer->Print("\n");
|
printer->Print("\n");
|
||||||
|
|
||||||
generateParseMethods(printer);
|
generateParseMethods(printer);
|
||||||
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSize()
|
// getSize()
|
||||||
|
printer->Print("//========== Size-related methods ===========\n");
|
||||||
generateGetSizeMethod(printer);
|
generateGetSizeMethod(printer);
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
|
if (!isBuilder) {
|
||||||
|
printer->Print("//========== Builder ===========\n");
|
||||||
|
generateBuilder(printer);
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
}
|
}
|
||||||
@@ -139,7 +148,6 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
|
|||||||
map <string, string> vars;
|
map <string, string> vars;
|
||||||
|
|
||||||
// mergeWith(other: Message)
|
// mergeWith(other: Message)
|
||||||
printer->Print("\n");
|
|
||||||
vars["className"] = getFullType();
|
vars["className"] = getFullType();
|
||||||
printer->Print(vars, "fun mergeWith (other: $className$) {\n");
|
printer->Print(vars, "fun mergeWith (other: $className$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
@@ -203,6 +211,7 @@ void ClassGenerator::generateWriteToMethod(io::Printer *printer) const {
|
|||||||
// generate code for serialization/deserialization of fields
|
// generate code for serialization/deserialization of fields
|
||||||
for (int i = 0; i < properties.size(); ++i) {
|
for (int i = 0; i < properties.size(); ++i) {
|
||||||
properties[i]->generateSerializationCode(printer, /* isRead = */ false, /* noTag = */ false);
|
properties[i]->generateSerializationCode(printer, /* isRead = */ false, /* noTag = */ false);
|
||||||
|
printer->Print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
@@ -319,7 +328,7 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const {
|
|||||||
printer->Print("return true");
|
printer->Print("return true");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n"); // parseFieldFrom body
|
printer->Print("}\n"); // parseFieldFrom body
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
// ====== parseFromWithSize(input: CodedInputStream, expectedSize: Int) =========
|
// ====== parseFromWithSize(input: CodedInputStream, expectedSize: Int) =========
|
||||||
printer->Print(vars,
|
printer->Print(vars,
|
||||||
@@ -346,7 +355,7 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const {
|
|||||||
|
|
||||||
printer->Outdent(); // function body
|
printer->Outdent(); // function body
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
// ======== parseFrom(input: CodedInputStream) =========
|
// ======== parseFrom(input: CodedInputStream) =========
|
||||||
printer->Print(vars,
|
printer->Print(vars,
|
||||||
@@ -375,7 +384,7 @@ void ClassGenerator::generateGetSizeMethod(io::Printer *printer) const {
|
|||||||
printer->Print("return size\n");
|
printer->Print("return size\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
// getSizeNoTag(): Int
|
// getSizeNoTag(): Int
|
||||||
printer->Print("fun getSizeNoTag(): Int {\n");
|
printer->Print("fun getSizeNoTag(): Int {\n");
|
||||||
|
|||||||
+41
-3
@@ -32,6 +32,10 @@ void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
|
|||||||
map<string, string> vars;
|
map<string, string> vars;
|
||||||
vars["name"] = simpleName;
|
vars["name"] = simpleName;
|
||||||
vars["field"] = getFullType();
|
vars["field"] = getFullType();
|
||||||
|
vars["protoType"] = getProtoType();
|
||||||
|
|
||||||
|
generateComment(printer);
|
||||||
|
|
||||||
printer->Print(vars, "var $name$ : $field$\n");
|
printer->Print(vars, "var $name$ : $field$\n");
|
||||||
|
|
||||||
// make setter private
|
// make setter private
|
||||||
@@ -93,13 +97,19 @@ void FieldGenerator::generateSerializationForPacked(io::Printer *printer, bool i
|
|||||||
*/
|
*/
|
||||||
FieldGenerator singleFieldGen = getUnderlyingTypeGenerator();
|
FieldGenerator singleFieldGen = getUnderlyingTypeGenerator();
|
||||||
singleFieldGen.simpleName = "singleElemSize";
|
singleFieldGen.simpleName = "singleElemSize";
|
||||||
|
|
||||||
|
printer->Print("\n");
|
||||||
singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ true, /* isField = */ false);
|
singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ true, /* isField = */ false);
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
printer->Print(vars, "val arraySize = expectedByteSize / singleElemSize\n");
|
printer->Print(vars, "val arraySize = expectedByteSize / singleElemSize\n");
|
||||||
|
|
||||||
// Allocate new array of estimated size
|
// Allocate new array of estimated size
|
||||||
printer->Print(vars, "val newArray = $arrayType$(arraySize)\n");
|
printer->Print(vars, "val newArray = $arrayType$(arraySize)\n");
|
||||||
|
|
||||||
|
// place declaration of new variable in anonymous scope for hygiene
|
||||||
|
printer->Print("run {\n");
|
||||||
|
printer->Indent();
|
||||||
printer->Print("var i = 0\n");
|
printer->Print("var i = 0\n");
|
||||||
printer->Print(vars, "while(i < arraySize) {\n");
|
printer->Print(vars, "while(i < arraySize) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
@@ -113,7 +123,10 @@ void FieldGenerator::generateSerializationForPacked(io::Printer *printer, bool i
|
|||||||
printer->Print(vars, "$fieldName$[i] = tmp\n");
|
printer->Print(vars, "$fieldName$[i] = tmp\n");
|
||||||
printer->Print("i += 1\n");
|
printer->Print("i += 1\n");
|
||||||
|
|
||||||
printer->Outdent();
|
printer->Outdent(); // while-loop
|
||||||
|
printer->Print("}\n");
|
||||||
|
|
||||||
|
printer->Outdent(); // anonymous scope
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -129,10 +142,17 @@ void FieldGenerator::generateSerializationForPacked(io::Printer *printer, bool i
|
|||||||
|
|
||||||
// length
|
// length
|
||||||
printer->Print(vars, "var arrayByteSize = 0\n");
|
printer->Print(vars, "var arrayByteSize = 0\n");
|
||||||
|
|
||||||
|
printer->Print("\n");
|
||||||
generateSizeEstimationCode(printer, "arrayByteSize", /* noTag = */ true, /* isField = */ false);
|
generateSizeEstimationCode(printer, "arrayByteSize", /* noTag = */ true, /* isField = */ false);
|
||||||
printer->Print(vars, "output.writeInt32NoTag(arrayByteSize)\n");
|
printer->Print(vars, "output.writeInt32NoTag(arrayByteSize)\n");
|
||||||
|
printer->Print("\n");
|
||||||
|
|
||||||
// all elements
|
// all elements
|
||||||
|
// place declaration of new variable in anonymous scope for hygiene
|
||||||
|
printer->Print("run {\n");
|
||||||
|
printer->Indent();
|
||||||
|
|
||||||
printer->Print("var i = 0\n");
|
printer->Print("var i = 0\n");
|
||||||
printer->Print(vars, "while (i < $fieldName$.size) {\n");
|
printer->Print(vars, "while (i < $fieldName$.size) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
@@ -145,7 +165,11 @@ void FieldGenerator::generateSerializationForPacked(io::Printer *printer, bool i
|
|||||||
singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ isPrimitive, /* isField = */ false);
|
singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ isPrimitive, /* isField = */ false);
|
||||||
|
|
||||||
printer->Print(vars, "i += 1\n");
|
printer->Print(vars, "i += 1\n");
|
||||||
printer->Outdent(); // for-loop
|
|
||||||
|
printer->Outdent(); // while-loop
|
||||||
|
printer->Print("}\n");
|
||||||
|
|
||||||
|
printer->Outdent(); // anonymous scope
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,6 +274,9 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
|||||||
vars["fieldName"] = simpleName;
|
vars["fieldName"] = simpleName;
|
||||||
vars["initValue"] = getInitValue();
|
vars["initValue"] = getInitValue();
|
||||||
|
|
||||||
|
if (isField) {
|
||||||
|
generateComment(printer);
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to generate syntax for serialization of repeated fields.
|
/* Try to generate syntax for serialization of repeated fields.
|
||||||
* Note that it should be first check because of Google's FieldDescriptor structure */
|
* Note that it should be first check because of Google's FieldDescriptor structure */
|
||||||
@@ -376,7 +403,7 @@ void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string var
|
|||||||
singleFieldGen.generateSizeEstimationCode(printer, "arraySize", noTag, /* isField = */ false);
|
singleFieldGen.generateSizeEstimationCode(printer, "arraySize", noTag, /* isField = */ false);
|
||||||
|
|
||||||
printer->Print(vars, "i += 1\n");
|
printer->Print(vars, "i += 1\n");
|
||||||
|
|
||||||
printer->Outdent(); // for-loop
|
printer->Outdent(); // for-loop
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
|
||||||
@@ -498,6 +525,17 @@ string FieldGenerator::getWireType() const {
|
|||||||
return name_resolving::protobufTypeToKotlinWireType(descriptor->type());
|
return name_resolving::protobufTypeToKotlinWireType(descriptor->type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FieldGenerator::generateComment(io::Printer *printer) const {
|
||||||
|
map <string, string> vars;
|
||||||
|
|
||||||
|
vars["repeated"] = descriptor->is_repeated() ? "repeated " : "";
|
||||||
|
vars["declared_type"] = descriptor->type_name();
|
||||||
|
vars["name"] = descriptor->name();
|
||||||
|
vars["number"] = std::to_string(descriptor->number());
|
||||||
|
|
||||||
|
printer->Print(vars, "//$repeated$$declared_type$ $name$ = $number$\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace kotlin
|
} // namespace kotlin
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
|
|||||||
+1
-2
@@ -22,13 +22,12 @@ class NameResolver; // declared in kotlin_name_resolver.h
|
|||||||
class FieldGenerator {
|
class FieldGenerator {
|
||||||
private:
|
private:
|
||||||
FieldDescriptor const * descriptor;
|
FieldDescriptor const * descriptor;
|
||||||
// TODO: refactor from field generator to some static utility namespace
|
|
||||||
|
|
||||||
void generateSetter(io::Printer * printer) const;
|
void generateSetter(io::Printer * printer) const;
|
||||||
|
void generateComment(io::Printer * printer) const;
|
||||||
void generateRepeatedMethods(io::Printer * printer, bool isBuilder) const;
|
void generateRepeatedMethods(io::Printer * printer, bool isBuilder) const;
|
||||||
|
|
||||||
void generateSerializationForPacked (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
void generateSerializationForPacked (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
||||||
void generateSerializationForRepeated (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
|
||||||
void generateSerializationForEnums (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
void generateSerializationForEnums (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
||||||
void generateSerializationForMessages (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
void generateSerializationForMessages (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
||||||
void generateSerializationForPrimitives (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
void generateSerializationForPrimitives (io::Printer * printer, bool isRead, bool noTag, bool isField) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user