Protobuf: refactored FieldGenerator interface heavily. Now it offers much more clearier interface for names getting (separating simple names from full-qualified names)
This commit is contained in:
@@ -23,9 +23,14 @@ $(BINDIR):
|
||||
mkdir -p $(BINDIR)
|
||||
|
||||
clean:
|
||||
rm -rf $(BINDIR) $(EXE)
|
||||
rm -rf $(BINDIR)
|
||||
|
||||
generate:
|
||||
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/addressbook.proto
|
||||
./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/nested-msg.proto
|
||||
.PHONY: clean all generate
|
||||
|
||||
debug:
|
||||
gdb --args ./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/addressbook.proto
|
||||
gdb --args ./protoc --kotlin_out=$$HOME/Downloads/carkot/proto/compiler/src ./test/nested-msg.proto
|
||||
|
||||
.PHONY: clean all generate debug
|
||||
|
||||
Binary file not shown.
+19
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Created by user on 7/20/16.
|
||||
//
|
||||
|
||||
#include "UnreachableStateException.h"
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace kotlin {
|
||||
|
||||
UnreachableStateException::UnreachableStateException(std::string const & what)
|
||||
: std::logic_error(what)
|
||||
{ }
|
||||
|
||||
} // namespace kotlin
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by user on 7/20/16.
|
||||
//
|
||||
|
||||
#ifndef GOOGLE_UNREACHABLESTATEEXCEPTION_H
|
||||
#define GOOGLE_UNREACHABLESTATEEXCEPTION_H
|
||||
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace kotlin {
|
||||
|
||||
class UnreachableStateException : public std::logic_error {
|
||||
public:
|
||||
UnreachableStateException(std::string const & what);
|
||||
};
|
||||
|
||||
} // namespace kotlin
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
|
||||
#endif //GOOGLE_UNREACHABLESTATEEXCEPTION_H
|
||||
+28
-46
@@ -80,8 +80,6 @@ ClassGenerator::ClassGenerator(Descriptor const *descriptor, NameResolver * name
|
||||
: descriptor(descriptor)
|
||||
, nameResolver(nameResolver)
|
||||
{
|
||||
simpleName = descriptor->name();
|
||||
|
||||
int field_count = descriptor->field_count();
|
||||
for (int i = 0; i < field_count; ++i) {
|
||||
FieldDescriptor const * fieldDescriptor = descriptor->field(i);
|
||||
@@ -91,14 +89,14 @@ 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(), nameResolver->getClassName(simpleName));
|
||||
nameResolver->addClass(nestedClassDescriptor->name(), getFullType());
|
||||
classesDeclarations.push_back(new ClassGenerator(nestedClassDescriptor, nameResolver));
|
||||
}
|
||||
|
||||
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(), nameResolver->getClassName(simpleName));
|
||||
nameResolver->addClass(nestedEnumDescriptor->name(), getFullType());
|
||||
enumsDeclaraions.push_back(new EnumGenerator(nestedEnumDescriptor));
|
||||
}
|
||||
|
||||
@@ -109,7 +107,7 @@ ClassGenerator::ClassGenerator(Descriptor const *descriptor, NameResolver * name
|
||||
*/
|
||||
std::sort(properties.begin(), properties.end(),
|
||||
[](FieldGenerator const * first, FieldGenerator const * second) {
|
||||
return first->fieldNumber < second->fieldNumber;
|
||||
return first->getFieldNumber() < second->getFieldNumber();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -137,7 +135,7 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
|
||||
|
||||
// mergeWith(other: Message)
|
||||
printer->Print("\n");
|
||||
vars["className"] = simpleName;
|
||||
vars["className"] = getFullType();
|
||||
printer->Print(vars, "fun mergeWith (other: $className$) {\n");
|
||||
printer->Indent();
|
||||
|
||||
@@ -145,12 +143,12 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
|
||||
vars["fieldName"] = properties[i]->simpleName;
|
||||
|
||||
// concatenate repeated fields
|
||||
if (properties[i]->modifier == FieldDescriptor::LABEL_REPEATED) {
|
||||
if (properties[i]->getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
printer->Print(vars, "$fieldName$.addAll(other.$fieldName$)\n");
|
||||
}
|
||||
|
||||
// Bytes type is handled separately
|
||||
else if (properties[i]->protoType == FieldDescriptor::TYPE_BYTES) {
|
||||
else if (properties[i]->getProtoType() == FieldDescriptor::TYPE_BYTES) {
|
||||
vars["initValue"] = properties[i]->getInitValue();
|
||||
printer->Print(vars, "$fieldName$.plus(other.$fieldName$)\n");
|
||||
}
|
||||
@@ -170,7 +168,7 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
|
||||
printer->Print(vars, "fun mergeFrom (input: CodedInputStream) {\n");
|
||||
printer->Indent();
|
||||
|
||||
vars["builderName"] = nameResolver->getBuilderName(simpleName);
|
||||
vars["builderName"] = getBuilderFullType();
|
||||
printer->Print(vars, "val builder = $builderName$()\n");
|
||||
printer->Print("mergeWith(builder.parseFrom(input).build())");
|
||||
|
||||
@@ -184,7 +182,7 @@ void ClassGenerator::generateSerializers(io::Printer *printer, bool isRead) cons
|
||||
vars["funName"]= isRead ? "readFrom" : "writeTo";
|
||||
vars["stream"] = isRead ? "CodedInputStream" : "CodedOutputStream";
|
||||
vars["arg"] = isRead ? "input" : "output";
|
||||
vars["returnType"] = isRead ? nameResolver->getBuilderName(simpleName) : "Unit";
|
||||
vars["returnType"] = isRead ? getBuilderFullType() : "Unit";
|
||||
vars["maybeReturn"] = isRead ? "return this\n" : "";
|
||||
|
||||
// generate function header
|
||||
@@ -209,14 +207,14 @@ 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) {
|
||||
argumentList += properties[i]->simpleName + ": " + properties[i]->fullType + " = " + properties[i]->getInitValue();
|
||||
argumentList += properties[i]->simpleName + ": " + properties[i]->getFullType() + " = " + properties[i]->getInitValue();
|
||||
if (i + 1 != properties.size()) {
|
||||
argumentList += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
map<string, string> vars;
|
||||
vars["name"] = isBuilder? "Builder" + simpleName : simpleName;
|
||||
vars["name"] = isBuilder? getBuidlerSimpleType() : getSimpleType();
|
||||
vars["argumentList"] = argumentList;
|
||||
vars["maybePrivate"] = isBuilder? "" : " private";
|
||||
printer->Print(vars,
|
||||
@@ -227,7 +225,7 @@ void ClassGenerator::generateHeader(io::Printer * printer, bool isBuilder) const
|
||||
|
||||
void ClassGenerator::generateBuildMethod(io::Printer * printer) const {
|
||||
map <string, string> vars;
|
||||
vars["returnType"] = simpleName;
|
||||
vars["returnType"] = getFullType();
|
||||
printer->Print(vars,
|
||||
"fun build(): $returnType$ {\n");
|
||||
printer->Indent();
|
||||
@@ -266,7 +264,7 @@ void ClassGenerator::generateInitSection(io::Printer * printer) const {
|
||||
void ClassGenerator::generateParseMethods(io::Printer *printer) const {
|
||||
// parseFieldFrom(input: CodedInputStream): Boolean
|
||||
map <string, string> vars;
|
||||
vars["builderName"] = nameResolver->getBuilderName(simpleName);
|
||||
vars["builderName"] = getBuilderFullType();
|
||||
|
||||
printer->Print("fun parseFieldFrom(input: CodedInputStream): Boolean {\n");
|
||||
printer->Indent();
|
||||
@@ -287,21 +285,21 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const {
|
||||
printer->Indent();
|
||||
|
||||
for (int i = 0; i < properties.size(); ++i) {
|
||||
vars["fieldNumber"] = std::to_string(properties[i]->fieldNumber);
|
||||
vars["fieldNumber"] = std::to_string(properties[i]->getFieldNumber());
|
||||
vars["kotlinFunSuffix"] = properties[i]->getKotlinFunctionSuffix();
|
||||
printer->Print(vars, "$fieldNumber$ -> ");
|
||||
|
||||
// code for serialization arrays and messages consists of more than one line and needs enclosing brackets
|
||||
if (properties[i]->modifier == FieldDescriptor::LABEL_REPEATED
|
||||
|| properties[i]->protoType == FieldDescriptor::TYPE_MESSAGE) {
|
||||
if (properties[i]->getProtoLabel() == FieldDescriptor::LABEL_REPEATED
|
||||
|| properties[i]->getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
}
|
||||
|
||||
properties[i]->generateSerializationCode(printer, /* isRead = */ true, /* noTag = */ true);
|
||||
|
||||
if (properties[i]->modifier == FieldDescriptor::LABEL_REPEATED
|
||||
|| properties[i]->protoType == FieldDescriptor::TYPE_MESSAGE) {
|
||||
if (properties[i]->getProtoLabel() == FieldDescriptor::LABEL_REPEATED
|
||||
|| properties[i]->getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
}
|
||||
@@ -339,36 +337,20 @@ void ClassGenerator::generateGetSizeMethod(io::Printer *printer) const {
|
||||
printer->Print("}\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int ClassGenerator::getSizeWithoutHeader() {
|
||||
// int size = 0;
|
||||
// for (int i = 0; i < properties.size(); ++i) {
|
||||
// size += properties[i].getSizeWithHeader();
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
|
||||
const string ClassModifier::getName() const {
|
||||
string result = "";
|
||||
switch (type) {
|
||||
case CLASS:
|
||||
result = "class";
|
||||
break;
|
||||
case INTERFACE:
|
||||
result = "interface";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
string ClassGenerator::getSimpleType() const {
|
||||
return descriptor->name();
|
||||
}
|
||||
|
||||
ClassModifier::ClassModifier(ClassModifier::Type type)
|
||||
: type(type)
|
||||
{ }
|
||||
string ClassGenerator::getFullType() const {
|
||||
return nameResolver->getClassName(getSimpleType());
|
||||
}
|
||||
|
||||
ClassModifier::ClassModifier() {
|
||||
type = CLASS;
|
||||
string ClassGenerator::getBuilderFullType() const {
|
||||
return nameResolver->getBuilderName(getSimpleType());
|
||||
}
|
||||
|
||||
string ClassGenerator::getBuidlerSimpleType() const {
|
||||
return "Builder" + getSimpleType();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+5
-16
@@ -20,24 +20,13 @@ namespace kotlin {
|
||||
class FieldGenerator; // declared in "kotlin_file_generator.h"
|
||||
class NameResolver; // declared in "kotlin_name_resolver.h"
|
||||
|
||||
// wrapper for enum CLASS/INTERFACE with convenience method of getting name
|
||||
class ClassModifier {
|
||||
public:
|
||||
enum Type {
|
||||
CLASS,
|
||||
INTERFACE
|
||||
};
|
||||
ClassModifier();
|
||||
ClassModifier(Type type);
|
||||
Type type;
|
||||
|
||||
string const getName() const;
|
||||
};
|
||||
|
||||
class ClassGenerator {
|
||||
public:
|
||||
string simpleName;
|
||||
string fullName;
|
||||
string getSimpleType() const;
|
||||
string getFullType() const;
|
||||
string getBuidlerSimpleType() const;
|
||||
string getBuilderFullType() const;
|
||||
|
||||
vector <FieldGenerator *> properties;
|
||||
vector <ClassGenerator *> classesDeclarations;
|
||||
vector <EnumGenerator *> enumsDeclaraions;
|
||||
|
||||
+105
-42
@@ -7,6 +7,7 @@
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include "kotlin_name_resolver.h"
|
||||
#include "UnreachableStateException.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace google {
|
||||
@@ -15,13 +16,22 @@ namespace compiler {
|
||||
namespace kotlin {
|
||||
|
||||
string FieldGenerator::getInitValue() const {
|
||||
return name_resolving::protobufTypeToInitValue(this);
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
return "mutableListOf()";
|
||||
}
|
||||
if (getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
return getBuilderFullType() + "().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;
|
||||
vars["field"] = name_resolving::protobufToKotlinField(descriptor);
|
||||
vars["field"] = getFullType();
|
||||
printer->Print(vars, "var $name$ : $field$\n");
|
||||
|
||||
// make setter private
|
||||
@@ -35,29 +45,25 @@ void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
|
||||
}
|
||||
|
||||
// generate additional methods for repeated fields
|
||||
if (modifier == FieldDescriptor::LABEL_REPEATED) {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
generateRepeatedMethods(printer, isBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerator const * enclosingClass, NameResolver * nameResolver)
|
||||
: descriptor(descriptor)
|
||||
, modifier(descriptor->label())
|
||||
, enclosingClass(enclosingClass)
|
||||
, simpleName(descriptor->name())
|
||||
, underlyingType(name_resolving::protobufToKotlinType(descriptor))
|
||||
, fullType(name_resolving::protobufToKotlinField(descriptor))
|
||||
, protoType(descriptor->type())
|
||||
, fieldNumber(descriptor->number())
|
||||
, nameResolver(nameResolver)
|
||||
, simpleName(descriptor->name())
|
||||
, protoLabel(descriptor->label())
|
||||
{ }
|
||||
|
||||
// TODO: long, complicated and messy method. Refactor it ASAP
|
||||
void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead, bool noTag) const {
|
||||
map <string, string> vars;
|
||||
vars["type"] = name_resolving::protobufTypeToKotlinFunctionSuffix(descriptor->type()) + (noTag ? "NoTag" : "");
|
||||
vars["fieldNumber"] = std::to_string(fieldNumber);
|
||||
vars["maybeFieldNumber"] = noTag ? "" : std::to_string(fieldNumber);
|
||||
vars["type"] = getKotlinFunctionSuffix() + (noTag ? "NoTag" : "");
|
||||
vars["fieldNumber"] = std::to_string(getFieldNumber());
|
||||
vars["maybeFieldNumber"] = noTag ? "" : std::to_string(getFieldNumber());
|
||||
vars["fieldName"] = simpleName;
|
||||
vars["arg"] = isRead ? "input" : "output";
|
||||
vars["maybeComma"] = ", ";
|
||||
@@ -70,7 +76,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
* - Write length as int32 (note that tag shouldn't be added)
|
||||
* - Write all repeated elements via recursive call (again, without tags)
|
||||
*/
|
||||
if (modifier == FieldDescriptor::LABEL_REPEATED) {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
// tag
|
||||
if (isRead) {
|
||||
if (!noTag) {
|
||||
@@ -90,7 +96,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
removed as soon as target code will support inheritance and interfaces.
|
||||
(then writing CodedOutputStream.writeMessage will be possible).
|
||||
*/
|
||||
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
|
||||
FieldGenerator singleFieldGen = getUnderlyingTypeGenerator();
|
||||
|
||||
/* Another dirty hack here: create tmp variable of a given type and read it from input stream
|
||||
then add that tmp var into list.
|
||||
@@ -99,11 +105,11 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
to ArrayOutOfIndex errors.
|
||||
*/
|
||||
// TODO: stub here, resolve name properly!
|
||||
vars["fieldType"] = underlyingType + ".Builder" + underlyingType;
|
||||
vars["initValue"] = underlyingType + ".Builder" + underlyingType + "()";
|
||||
printer->Print(vars, "val tmp: $fieldType$ = $initValue$\n");
|
||||
vars["builderType"] = getUnderlyingTypeGenerator().getFullType();
|
||||
vars["initValue"] = getUnderlyingTypeGenerator().getInitValue();
|
||||
printer->Print(vars, "val tmp: $builderType$ = $initValue$\n");
|
||||
singleFieldGen.simpleName = "tmp";
|
||||
singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL;
|
||||
singleFieldGen.protoLabel = FieldDescriptor::LABEL_OPTIONAL;
|
||||
|
||||
// Note that primitive types are packed by default in proto3, i.e. they are should be written without tag
|
||||
bool isPrimitive = descriptor->type() != FieldDescriptor::TYPE_BYTES &&
|
||||
@@ -112,9 +118,9 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
descriptor->type() != FieldDescriptor::TYPE_ENUM;
|
||||
|
||||
singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ isPrimitive);
|
||||
singleFieldGen.generateSizeEstimationCode(printer, "readSize"); // add size of current element to total size
|
||||
singleFieldGen.generateSizeEstimationCode(printer, /* varName = */ "readSize"); // add size of current element to total size
|
||||
|
||||
printer->Print(vars, "$fieldName$.add(tmp.build())\n");
|
||||
printer->Print(vars, "$fieldName$.add(tmp)\n");
|
||||
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
@@ -138,7 +144,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
// hack: see above
|
||||
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
|
||||
singleFieldGen.simpleName = "item";
|
||||
singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL;
|
||||
singleFieldGen.protoLabel = FieldDescriptor::LABEL_OPTIONAL;
|
||||
|
||||
// TODO: maybe refactor this in name_resolving or separate method at least
|
||||
// Note that primitive types are packed by default in proto3, i.e. they are should be written without tag
|
||||
@@ -167,7 +173,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
Example: output.writeEnum(42, enumField.ord)
|
||||
*/
|
||||
if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
|
||||
vars["converter"] = underlyingType + ".fromIntTo" + underlyingType;
|
||||
vars["converter"] = getEnumFromIntConverter();
|
||||
if (isRead) {
|
||||
printer->Print(vars, "$fieldName$ = $converter$(input.read$type$($maybeFieldNumber$))\n");
|
||||
}
|
||||
@@ -185,7 +191,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
*/
|
||||
if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
if (isRead) {
|
||||
vars["fieldNumber"] = std::to_string(fieldNumber);
|
||||
vars["fieldNumber"] = std::to_string(getFieldNumber());
|
||||
vars["dollar"] = "$";
|
||||
|
||||
// read tag
|
||||
@@ -205,7 +211,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
|
||||
"\") }\n");
|
||||
}
|
||||
else {
|
||||
vars["fieldNumber"] = std::to_string(fieldNumber);
|
||||
vars["fieldNumber"] = std::to_string(getFieldNumber());
|
||||
// write tag
|
||||
printer->Print(vars, "output.writeTag($fieldNumber$, WireType.LENGTH_DELIMITED)\n");
|
||||
|
||||
@@ -233,8 +239,8 @@ void FieldGenerator::generateSetter(io::Printer *printer) const {
|
||||
map <string, string> vars;
|
||||
vars["camelCaseName"] = name_resolving::makeFirstLetterUpper(simpleName);
|
||||
vars["fieldName"] = simpleName;
|
||||
vars["builderName"] = nameResolver->getBuilderName(enclosingClass->simpleName);
|
||||
vars["type"] = fullType;
|
||||
vars["builderName"] = enclosingClass->getBuilderFullType();
|
||||
vars["type"] = getFullType();
|
||||
printer->Print(vars,
|
||||
"fun set$camelCaseName$(value: $type$): $builderName$ {\n");
|
||||
printer->Indent();
|
||||
@@ -247,10 +253,10 @@ void FieldGenerator::generateSetter(io::Printer *printer) const {
|
||||
|
||||
void FieldGenerator::generateRepeatedMethods(io::Printer * printer, bool isBuilder) const {
|
||||
map <string, string> vars;
|
||||
vars["elementType"] = underlyingType;
|
||||
vars["elementType"] = getUnderlyingTypeGenerator().getSimpleType();
|
||||
vars["arg"] = "value";
|
||||
vars["fieldName"] = simpleName;
|
||||
vars["builderName"] = nameResolver->getBuilderName(underlyingType); // TODO: call to non-existent field in map.
|
||||
vars["builderName"] = enclosingClass->getBuilderFullType(); // TODO: call to non-existent field in map.
|
||||
|
||||
// generate indexed setter for builders
|
||||
if (isBuilder) {
|
||||
@@ -292,21 +298,14 @@ string FieldGenerator::getKotlinFunctionSuffix() const {
|
||||
return name_resolving::protobufTypeToKotlinFunctionSuffix(descriptor->type());
|
||||
}
|
||||
|
||||
string FieldGenerator::getUnderlyingTypeInitValue() const {
|
||||
if (protoType == FieldDescriptor::TYPE_MESSAGE) {
|
||||
return "Builder" + underlyingType + "().build()";
|
||||
}
|
||||
return name_resolving::protobufTypeToInitValue(this);
|
||||
}
|
||||
|
||||
void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string varName, bool noTag) const {
|
||||
map<string, string> vars;
|
||||
vars["varName"] = varName;
|
||||
vars["fieldName"] = simpleName;
|
||||
vars["fieldNumber"] = std::to_string(fieldNumber);
|
||||
vars["fieldNumber"] = std::to_string(getFieldNumber());
|
||||
|
||||
// First of all, generate code for repeated fields
|
||||
if (modifier == FieldDescriptor::LABEL_REPEATED) {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
// We will need total byte size of array, because that size is itself a part of the message and
|
||||
// adds to total message size.
|
||||
// For the sake of hygiene, temporary variables are created in anonymous scope
|
||||
@@ -322,7 +321,7 @@ void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string var
|
||||
|
||||
// hack: reuse generateSizeEstimationCode in the same manner as in generateSerializationCode
|
||||
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
|
||||
singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL;
|
||||
singleFieldGen.protoLabel = FieldDescriptor::LABEL_OPTIONAL;
|
||||
singleFieldGen.simpleName = "item";
|
||||
singleFieldGen.generateSizeEstimationCode(printer, "arraySize");
|
||||
|
||||
@@ -348,7 +347,7 @@ void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string var
|
||||
|
||||
// Then, call getSize recursively for nested messages
|
||||
// TODO: currently suboptimal repeatative calls getSize() are being made. We can optimize it later via caching calls to getSize()
|
||||
if (protoType == FieldDescriptor::TYPE_MESSAGE) {
|
||||
if (getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
// don't forget about tag and length annotation
|
||||
printer->Print(vars, "$varName$ += $fieldName$.getSize()"
|
||||
" + "
|
||||
@@ -360,18 +359,82 @@ void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string var
|
||||
}
|
||||
|
||||
// Next, process enums as they should be casted to ints manually
|
||||
if (protoType == FieldDescriptor::TYPE_ENUM) {
|
||||
vars["enumName"] = fullType;
|
||||
if (getProtoType() == FieldDescriptor::TYPE_ENUM) {
|
||||
printer->Print(vars, "$varName$ += WireFormat.getEnumSize($fieldNumber$, $fieldName$.ord)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Finally, get size of all primitive types trivially via call to WireFormat in runtime
|
||||
vars["kotlinSuffix"] = name_resolving::protobufTypeToKotlinFunctionSuffix(descriptor->type());
|
||||
vars["kotlinSuffix"] = getKotlinFunctionSuffix();
|
||||
printer->Print(vars, "$varName$ += WireFormat.get$kotlinSuffix$Size($fieldNumber$, $fieldName$)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FieldDescriptor::Label FieldGenerator::getProtoLabel() const {
|
||||
return protoLabel;
|
||||
}
|
||||
|
||||
FieldDescriptor::Type FieldGenerator::getProtoType() const {
|
||||
return descriptor->type();
|
||||
}
|
||||
|
||||
int FieldGenerator::getFieldNumber() const {
|
||||
return descriptor->number();
|
||||
}
|
||||
|
||||
|
||||
string FieldGenerator::getSimpleType() const {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
return "MutableList <" + getUnderlyingTypeGenerator().getSimpleType() + ">";
|
||||
}
|
||||
if (getProtoType() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
return descriptor->message_type()->name();
|
||||
}
|
||||
if (getProtoType() == FieldDescriptor::TYPE_ENUM) {
|
||||
return descriptor->enum_type()->name();
|
||||
}
|
||||
return name_resolving::protobufToKotlinType(descriptor->type());
|
||||
}
|
||||
|
||||
string FieldGenerator::getFullType() const {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
return "MutableList <" + getUnderlyingTypeGenerator().getFullType() + ">";
|
||||
}
|
||||
if (getProtoType() == FieldDescriptor::TYPE_MESSAGE ||
|
||||
getProtoType() == FieldDescriptor::TYPE_ENUM) {
|
||||
return nameResolver->getClassName(getSimpleType());
|
||||
}
|
||||
return name_resolving::protobufToKotlinType(getProtoType());
|
||||
}
|
||||
|
||||
string FieldGenerator::getBuilderFullType() const {
|
||||
if (getProtoType() != FieldDescriptor::TYPE_MESSAGE) {
|
||||
throw UnreachableStateException("Error: trying to get builder name for non-message field " + simpleName);
|
||||
}
|
||||
return nameResolver->getBuilderName(getSimpleType());
|
||||
}
|
||||
|
||||
string FieldGenerator::getBuilderSimpleType() const {
|
||||
if (getProtoType() != FieldDescriptor::TYPE_MESSAGE) {
|
||||
throw UnreachableStateException("Error: trying to get builder name for non-message field " + simpleName);
|
||||
}
|
||||
return "Builder" + getSimpleType();
|
||||
}
|
||||
|
||||
string FieldGenerator::getEnumFromIntConverter() const {
|
||||
return getFullType() + ".fromIntTo" + getSimpleType();
|
||||
}
|
||||
|
||||
FieldGenerator FieldGenerator::getUnderlyingTypeGenerator() const {
|
||||
if (getProtoLabel() == FieldDescriptor::LABEL_REPEATED) {
|
||||
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
|
||||
singleFieldGen.protoLabel = FieldDescriptor::LABEL_OPTIONAL;
|
||||
return singleFieldGen;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace kotlin
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
|
||||
+45
-19
@@ -27,32 +27,58 @@ private:
|
||||
void generateSetter(io::Printer * printer) const;
|
||||
void generateRepeatedMethods(io::Printer * printer, bool isBuilder) const;
|
||||
public:
|
||||
FieldDescriptor::Label modifier;
|
||||
ClassGenerator const * enclosingClass; // class, in which that field is defined
|
||||
string simpleName;
|
||||
string underlyingType; // unwrapped type.
|
||||
|
||||
/**
|
||||
* Full type of field.
|
||||
* fullType = Array<underlyingType> for REPEATED fields
|
||||
* fullType = underlyingType? for OPTIONAL fields
|
||||
* fullType = underlyingType for all other cases
|
||||
*/
|
||||
string fullType;
|
||||
string builderName;
|
||||
string fullName;
|
||||
string getInitValue() const;
|
||||
string getUnderlyingTypeInitValue() const;
|
||||
FieldDescriptor::Type protoType;
|
||||
int fieldNumber;
|
||||
NameResolver * nameResolver;
|
||||
string simpleName;
|
||||
|
||||
FieldDescriptor::Label protoLabel; // TODO: hack here - this field is used for some dark magic that allows us to drop generics from the generated code
|
||||
|
||||
FieldDescriptor::Label getProtoLabel() const;
|
||||
FieldDescriptor::Type getProtoType() const;
|
||||
|
||||
/* Return declared tag number */
|
||||
int getFieldNumber() const;
|
||||
|
||||
/* Returns instance of FieldGenerator, that generated underlying type for repeated fields.
|
||||
* For non-repeated fields, returns `this` */
|
||||
FieldGenerator getUnderlyingTypeGenerator() const;
|
||||
|
||||
/* For repeated fields, returns simple name of single element.
|
||||
* For all other cases, returns simple name of field, which is the same as getType()
|
||||
*/
|
||||
|
||||
/* For repeated fields, return simple name of single element, wrapped into corresponding Kotlin array type
|
||||
* Example: Array<NestedMessage>
|
||||
* For other types, return simple name (without full-qualification for non-primitive types) of field's type
|
||||
*/
|
||||
string getSimpleType() const;
|
||||
|
||||
string getBuilderSimpleType() const;
|
||||
|
||||
/* Returns full=qualified name of builder if field type is user-defined message */
|
||||
string getBuilderFullType() const;
|
||||
|
||||
/* Returns the same as getType(), but with full-qualification for non-primitive types if necessary.
|
||||
* Example: Array<EnclosingMessage.NestedMessage>
|
||||
*/
|
||||
string getFullType() const;
|
||||
|
||||
/* Returns initial value of this field's type.
|
||||
* Note that full qualification for non-primitive types will always used here.
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
string getKotlinFunctionSuffix() const;
|
||||
|
||||
/* Return function name in enum namespace that converts from enum to Int */
|
||||
string getEnumFromIntConverter() const;
|
||||
void generateCode(io::Printer * printer, bool isBuilder) const;
|
||||
void generateSerializationCode(io::Printer * printer, bool isRead = false, bool noTag = false) const;
|
||||
void generateSizeEstimationCode(io::Printer * printer, string varName, bool noTag = false) const;
|
||||
FieldGenerator(FieldDescriptor const * descriptor, ClassGenerator const * enclosingClass, NameResolver * nameResolver);
|
||||
string getKotlinFunctionSuffix() const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace kotlin
|
||||
|
||||
+11
-32
@@ -5,7 +5,7 @@
|
||||
#include "kotlin_name_resolver.h"
|
||||
#include "kotlin_field_generator.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include "UnreachableStateException.h"
|
||||
#include <string>
|
||||
|
||||
namespace google {
|
||||
@@ -33,8 +33,7 @@ string getKotlinOutputByProtoName(string protoName) {
|
||||
return justName + ".kt";
|
||||
}
|
||||
|
||||
string protobufToKotlinType(FieldDescriptor const * descriptor) {
|
||||
FieldDescriptor::Type type = descriptor->type();
|
||||
string protobufToKotlinType(FieldDescriptor::Type type) {
|
||||
switch(type) {
|
||||
case FieldDescriptor::TYPE_BOOL:
|
||||
return "Boolean";
|
||||
@@ -43,7 +42,8 @@ string protobufToKotlinType(FieldDescriptor const * descriptor) {
|
||||
case FieldDescriptor::TYPE_DOUBLE:
|
||||
return "Double";
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
return string(descriptor->enum_type()->name());
|
||||
throw UnreachableStateException
|
||||
("Error: mapping protobuf enum types to kotlin types should be resolved by field generator, not by protobufToKotlinType function");
|
||||
case FieldDescriptor::TYPE_FIXED32:
|
||||
// we map uint32 into Int, storing top bit in sign bit
|
||||
return "Int";
|
||||
@@ -57,7 +57,8 @@ string protobufToKotlinType(FieldDescriptor const * descriptor) {
|
||||
case FieldDescriptor::TYPE_INT64:
|
||||
return "Long";
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
return string(descriptor->message_type()->name());
|
||||
throw UnreachableStateException
|
||||
("Error: mapping protobuf message types to kotlin types should be resolved by field generator, not by protobufToKotlinType function");
|
||||
case FieldDescriptor::TYPE_SFIXED32:
|
||||
return "Int";
|
||||
case FieldDescriptor::TYPE_SFIXED64:
|
||||
@@ -67,7 +68,7 @@ string protobufToKotlinType(FieldDescriptor const * descriptor) {
|
||||
case FieldDescriptor::TYPE_SINT64:
|
||||
return "Long";
|
||||
case FieldDescriptor::TYPE_STRING:
|
||||
return "kotlin.String";
|
||||
return "String";
|
||||
case FieldDescriptor::TYPE_UINT32:
|
||||
return "Int"; // see notes for TYPE_FIXED32
|
||||
case FieldDescriptor::TYPE_UINT64:
|
||||
@@ -75,30 +76,9 @@ string protobufToKotlinType(FieldDescriptor const * descriptor) {
|
||||
}
|
||||
}
|
||||
|
||||
string protobufToKotlinField(FieldDescriptor const * descriptor) {
|
||||
FieldDescriptor::Label modifier = descriptor->label();
|
||||
string preamble = "",
|
||||
postamble = "";
|
||||
switch (modifier) {
|
||||
case FieldDescriptor::LABEL_REQUIRED:
|
||||
break;
|
||||
case FieldDescriptor::LABEL_OPTIONAL:
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
preamble = "MutableList <";
|
||||
postamble = "> ";
|
||||
break;
|
||||
}
|
||||
return preamble + protobufToKotlinType(descriptor) + postamble;
|
||||
}
|
||||
|
||||
// TODO: think about nested arrays
|
||||
string protobufTypeToInitValue(FieldGenerator const * fieldGen) {
|
||||
if (fieldGen->modifier == FieldDescriptor::LABEL_REPEATED) {
|
||||
return "mutableListOf()";
|
||||
}
|
||||
|
||||
FieldDescriptor::Type type = fieldGen->protoType;
|
||||
string protobufTypeToInitValue(FieldDescriptor::Type type) {
|
||||
switch(type) {
|
||||
case FieldDescriptor::TYPE_BOOL:
|
||||
return "false";
|
||||
@@ -106,9 +86,8 @@ string protobufTypeToInitValue(FieldGenerator const * fieldGen) {
|
||||
return "ByteArray(0)";
|
||||
case FieldDescriptor::TYPE_DOUBLE:
|
||||
return "0.0";
|
||||
case FieldDescriptor::TYPE_ENUM: {
|
||||
return fieldGen->nameResolver->getClassName(fieldGen->fullType) + ".fromIntTo" + fieldGen->fullType + "(0)"; // produce enum from 0, as demanded by Google
|
||||
}
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
throw UnreachableStateException("Error: getting init values of enums should be handled by FieldGenerator, not by protobufToInitValue");
|
||||
case FieldDescriptor::TYPE_FIXED32:
|
||||
return "0";
|
||||
case FieldDescriptor::TYPE_FIXED64:
|
||||
@@ -120,7 +99,7 @@ string protobufTypeToInitValue(FieldGenerator const * fieldGen) {
|
||||
case FieldDescriptor::TYPE_INT64:
|
||||
return "0L";
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
return fieldGen->nameResolver->getBuilderName(fieldGen->fullType) + "().build()";
|
||||
throw UnreachableStateException("Error: getting init values of enums should be handled by FieldGenerator, not by protobufToInitValue");
|
||||
case FieldDescriptor::TYPE_SFIXED32:
|
||||
return "0";
|
||||
case FieldDescriptor::TYPE_SFIXED64:
|
||||
|
||||
+2
-4
@@ -37,11 +37,9 @@ std::string getFileNameWithoutExtension(std::string fullName);
|
||||
|
||||
std::string getKotlinOutputByProtoName(std::string protoName);
|
||||
|
||||
std::string protobufTypeToInitValue(FieldGenerator const * fieldGenerator);
|
||||
std::string protobufTypeToInitValue(FieldDescriptor::Type type);
|
||||
|
||||
std::string protobufToKotlinField(FieldDescriptor const * descriptor);
|
||||
|
||||
std::string protobufToKotlinType(FieldDescriptor const * descriptor);
|
||||
std::string protobufToKotlinType(FieldDescriptor::Type type);
|
||||
|
||||
/**
|
||||
* Converts one of protobuf wire types to corresponding Kotlin type with proper
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
class Person private constructor (name: kotlin.String = "", id: Int = 0, email: kotlin.String = "", phones: MutableList <PhoneNumber> = mutableListOf(), someBytes: ByteArray = ByteArray(0)) {
|
||||
var name : kotlin.String
|
||||
class Person private constructor (name: String = "", id: Int = 0, email: String = "", phones: MutableList <Person.PhoneNumber> = mutableListOf(), someBytes: ByteArray = ByteArray(0)) {
|
||||
var name : String
|
||||
private set
|
||||
|
||||
var id : Int
|
||||
private set
|
||||
|
||||
var email : kotlin.String
|
||||
var email : String
|
||||
private set
|
||||
|
||||
var phones : MutableList <PhoneNumber>
|
||||
var phones : MutableList <Person.PhoneNumber>
|
||||
private set
|
||||
|
||||
var someBytes : ByteArray
|
||||
@@ -38,11 +38,11 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
}
|
||||
}
|
||||
}
|
||||
class PhoneNumber private constructor (number: kotlin.String = "", type: PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
|
||||
var number : kotlin.String
|
||||
class PhoneNumber private constructor (number: String = "", type: Person.PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
|
||||
var number : String
|
||||
private set
|
||||
|
||||
var type : PhoneType
|
||||
var type : Person.PhoneType
|
||||
private set
|
||||
|
||||
|
||||
@@ -56,17 +56,17 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
output.writeEnum (2, type.ord)
|
||||
}
|
||||
|
||||
class BuilderPhoneNumber constructor (number: kotlin.String = "", type: PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
|
||||
var number : kotlin.String
|
||||
class BuilderPhoneNumber constructor (number: String = "", type: Person.PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
|
||||
var number : String
|
||||
private set
|
||||
fun setNumber(value: kotlin.String): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
fun setNumber(value: String): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
number = value
|
||||
return this
|
||||
}
|
||||
|
||||
var type : PhoneType
|
||||
var type : Person.PhoneType
|
||||
private set
|
||||
fun setType(value: PhoneType): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
fun setType(value: Person.PhoneType): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
type = value
|
||||
return this
|
||||
}
|
||||
@@ -79,12 +79,12 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
|
||||
fun readFrom (input: CodedInputStream): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
number = input.readString(1)
|
||||
type = PhoneType.fromIntToPhoneType(input.readEnum(2))
|
||||
type = Person.PhoneType.fromIntToPhoneType(input.readEnum(2))
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): PhoneNumber {
|
||||
return PhoneNumber(number, type)
|
||||
fun build(): Person.PhoneNumber {
|
||||
return Person.PhoneNumber(number, type)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
@@ -95,7 +95,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
val wireType = WireFormat.getTagWireType(tag)
|
||||
when(fieldNumber) {
|
||||
1 -> number = input.readStringNoTag()
|
||||
2 -> type = PhoneType.fromIntToPhoneType(input.readEnumNoTag())
|
||||
2 -> type = Person.PhoneType.fromIntToPhoneType(input.readEnumNoTag())
|
||||
}
|
||||
return true}
|
||||
fun parseFrom(input: CodedInputStream): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
@@ -111,7 +111,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: PhoneNumber) {
|
||||
fun mergeWith (other: Person.PhoneNumber) {
|
||||
number = other.number
|
||||
type = other.type
|
||||
}
|
||||
@@ -152,10 +152,10 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
output.writeBytes (5, someBytes)
|
||||
}
|
||||
|
||||
class BuilderPerson constructor (name: kotlin.String = "", id: Int = 0, email: kotlin.String = "", phones: MutableList <PhoneNumber> = mutableListOf(), someBytes: ByteArray = ByteArray(0)) {
|
||||
var name : kotlin.String
|
||||
class BuilderPerson constructor (name: String = "", id: Int = 0, email: String = "", phones: MutableList <Person.PhoneNumber> = mutableListOf(), someBytes: ByteArray = ByteArray(0)) {
|
||||
var name : String
|
||||
private set
|
||||
fun setName(value: kotlin.String): Person.BuilderPerson {
|
||||
fun setName(value: String): Person.BuilderPerson {
|
||||
name = value
|
||||
return this
|
||||
}
|
||||
@@ -167,28 +167,28 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
return this
|
||||
}
|
||||
|
||||
var email : kotlin.String
|
||||
var email : String
|
||||
private set
|
||||
fun setEmail(value: kotlin.String): Person.BuilderPerson {
|
||||
fun setEmail(value: String): Person.BuilderPerson {
|
||||
email = value
|
||||
return this
|
||||
}
|
||||
|
||||
var phones : MutableList <PhoneNumber>
|
||||
var phones : MutableList <Person.PhoneNumber>
|
||||
private set
|
||||
fun setPhones(value: MutableList <PhoneNumber> ): Person.BuilderPerson {
|
||||
fun setPhones(value: MutableList <Person.PhoneNumber>): Person.BuilderPerson {
|
||||
phones = value
|
||||
return this
|
||||
}
|
||||
fun setPhoneNumber(index: Int, value: PhoneNumber): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
fun setPhoneNumber(index: Int, value: PhoneNumber): Person.BuilderPerson {
|
||||
phones[index] = value
|
||||
return this
|
||||
}
|
||||
fun addPhoneNumber(value: PhoneNumber): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
fun addPhoneNumber(value: PhoneNumber): Person.BuilderPerson {
|
||||
phones.add(value)
|
||||
return this
|
||||
}
|
||||
fun addAllPhoneNumber(value: Iterable<PhoneNumber>): Person.PhoneNumber.BuilderPhoneNumber {
|
||||
fun addAllPhoneNumber(value: Iterable<PhoneNumber>): Person.BuilderPerson {
|
||||
for (item in value) {
|
||||
phones.add(item)
|
||||
}
|
||||
@@ -219,13 +219,13 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
|
||||
val tmp: Person.PhoneNumber = Person.PhoneNumber.BuilderPhoneNumber().build()
|
||||
input.readTag(4, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
tmp.mergeFrom(input)
|
||||
if (expectedSize != tmp.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${tmp.getSize()}") }
|
||||
readSize += tmp.getSize() + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(tmp.getSize())
|
||||
phones.add(tmp.build())
|
||||
phones.add(tmp)
|
||||
}
|
||||
someBytes = input.readBytes(5)
|
||||
return this
|
||||
@@ -249,13 +249,13 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
|
||||
val tmp: Person.PhoneNumber = Person.PhoneNumber.BuilderPhoneNumber().build()
|
||||
input.readTag(4, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
tmp.mergeFrom(input)
|
||||
if (expectedSize != tmp.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${tmp.getSize()}") }
|
||||
readSize += tmp.getSize() + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(tmp.getSize())
|
||||
phones.add(tmp.build())
|
||||
phones.add(tmp)
|
||||
}
|
||||
}
|
||||
5 -> someBytes = input.readBytesNoTag()
|
||||
@@ -312,8 +312,8 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
|
||||
}
|
||||
|
||||
|
||||
class AddressBook private constructor (people: MutableList <Person> = mutableListOf()) {
|
||||
var people : MutableList <Person>
|
||||
class AddressBook private constructor (people: MutableList <Person> = mutableListOf()) {
|
||||
var people : MutableList <Person>
|
||||
private set
|
||||
|
||||
|
||||
@@ -341,22 +341,22 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
|
||||
}
|
||||
}
|
||||
|
||||
class BuilderAddressBook constructor (people: MutableList <Person> = mutableListOf()) {
|
||||
var people : MutableList <Person>
|
||||
class BuilderAddressBook constructor (people: MutableList <Person> = mutableListOf()) {
|
||||
var people : MutableList <Person>
|
||||
private set
|
||||
fun setPeople(value: MutableList <Person> ): AddressBook.BuilderAddressBook {
|
||||
fun setPeople(value: MutableList <Person>): AddressBook.BuilderAddressBook {
|
||||
people = value
|
||||
return this
|
||||
}
|
||||
fun setPerson(index: Int, value: Person): Person.BuilderPerson {
|
||||
fun setPerson(index: Int, value: Person): AddressBook.BuilderAddressBook {
|
||||
people[index] = value
|
||||
return this
|
||||
}
|
||||
fun addPerson(value: Person): Person.BuilderPerson {
|
||||
fun addPerson(value: Person): AddressBook.BuilderAddressBook {
|
||||
people.add(value)
|
||||
return this
|
||||
}
|
||||
fun addAllPerson(value: Iterable<Person>): Person.BuilderPerson {
|
||||
fun addAllPerson(value: Iterable<Person>): AddressBook.BuilderAddressBook {
|
||||
for (item in value) {
|
||||
people.add(item)
|
||||
}
|
||||
@@ -373,13 +373,13 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: Person.BuilderPerson = Person.BuilderPerson()
|
||||
val tmp: Person = Person.BuilderPerson().build()
|
||||
input.readTag(1, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
tmp.mergeFrom(input)
|
||||
if (expectedSize != tmp.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${tmp.getSize()}") }
|
||||
readSize += tmp.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(tmp.getSize())
|
||||
people.add(tmp.build())
|
||||
people.add(tmp)
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -399,13 +399,13 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
var readSize = 0
|
||||
while(readSize != expectedSize) {
|
||||
val tmp: Person.BuilderPerson = Person.BuilderPerson()
|
||||
val tmp: Person = Person.BuilderPerson().build()
|
||||
input.readTag(1, WireType.LENGTH_DELIMITED)
|
||||
val expectedSize = input.readInt32NoTag()
|
||||
tmp.mergeFrom(input)
|
||||
if (expectedSize != tmp.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${tmp.getSize()}") }
|
||||
readSize += tmp.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(tmp.getSize())
|
||||
people.add(tmp.build())
|
||||
people.add(tmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2().build()) {
|
||||
var field1 : Level2
|
||||
class Level1 private constructor (field1: Level1.Level2 = Level1.Level2.BuilderLevel2().build()) {
|
||||
var field1 : Level1.Level2
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.field1 = field1
|
||||
}
|
||||
class Level2 private constructor (field2: Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
|
||||
var field2 : Level3
|
||||
class Level2 private constructor (field2: Level1.Level2.Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
|
||||
var field2 : Level1.Level2.Level3
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.field2 = field2
|
||||
}
|
||||
class Level3 private constructor (field3: Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
|
||||
var field3 : Level4
|
||||
class Level3 private constructor (field3: Level1.Level2.Level3.Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
|
||||
var field3 : Level1.Level2.Level3.Level4
|
||||
private set
|
||||
|
||||
|
||||
init {
|
||||
this.field3 = field3
|
||||
}
|
||||
class Level4 private constructor (field4: kotlin.String = "") {
|
||||
var field4 : kotlin.String
|
||||
class Level4 private constructor (field4: String = "") {
|
||||
var field4 : String
|
||||
private set
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
output.writeString (4, field4)
|
||||
}
|
||||
|
||||
class BuilderLevel4 constructor (field4: kotlin.String = "") {
|
||||
var field4 : kotlin.String
|
||||
class BuilderLevel4 constructor (field4: String = "") {
|
||||
var field4 : String
|
||||
private set
|
||||
fun setField4(value: kotlin.String): Level1.Level2.Level3.Level4.BuilderLevel4 {
|
||||
fun setField4(value: String): Level1.Level2.Level3.Level4.BuilderLevel4 {
|
||||
field4 = value
|
||||
return this
|
||||
}
|
||||
@@ -53,8 +53,8 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Level4 {
|
||||
return Level4(field4)
|
||||
fun build(): Level1.Level2.Level3.Level4 {
|
||||
return Level1.Level2.Level3.Level4(field4)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
@@ -79,7 +79,7 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: Level4) {
|
||||
fun mergeWith (other: Level1.Level2.Level3.Level4) {
|
||||
field4 = other.field4
|
||||
}
|
||||
|
||||
@@ -100,10 +100,10 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
field3.writeTo(output)
|
||||
}
|
||||
|
||||
class BuilderLevel3 constructor (field3: Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
|
||||
var field3 : Level4
|
||||
class BuilderLevel3 constructor (field3: Level1.Level2.Level3.Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
|
||||
var field3 : Level1.Level2.Level3.Level4
|
||||
private set
|
||||
fun setField3(value: Level4): Level1.Level2.Level3.BuilderLevel3 {
|
||||
fun setField3(value: Level1.Level2.Level3.Level4): Level1.Level2.Level3.BuilderLevel3 {
|
||||
field3 = value
|
||||
return this
|
||||
}
|
||||
@@ -121,8 +121,8 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Level3 {
|
||||
return Level3(field3)
|
||||
fun build(): Level1.Level2.Level3 {
|
||||
return Level1.Level2.Level3(field3)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
@@ -152,7 +152,7 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: Level3) {
|
||||
fun mergeWith (other: Level1.Level2.Level3) {
|
||||
field3 = other.field3
|
||||
}
|
||||
|
||||
@@ -173,10 +173,10 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
field2.writeTo(output)
|
||||
}
|
||||
|
||||
class BuilderLevel2 constructor (field2: Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
|
||||
var field2 : Level3
|
||||
class BuilderLevel2 constructor (field2: Level1.Level2.Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
|
||||
var field2 : Level1.Level2.Level3
|
||||
private set
|
||||
fun setField2(value: Level3): Level1.Level2.BuilderLevel2 {
|
||||
fun setField2(value: Level1.Level2.Level3): Level1.Level2.BuilderLevel2 {
|
||||
field2 = value
|
||||
return this
|
||||
}
|
||||
@@ -194,8 +194,8 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): Level2 {
|
||||
return Level2(field2)
|
||||
fun build(): Level1.Level2 {
|
||||
return Level1.Level2(field2)
|
||||
}
|
||||
|
||||
fun parseFieldFrom(input: CodedInputStream): Boolean {
|
||||
@@ -225,7 +225,7 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
}
|
||||
|
||||
|
||||
fun mergeWith (other: Level2) {
|
||||
fun mergeWith (other: Level1.Level2) {
|
||||
field2 = other.field2
|
||||
}
|
||||
|
||||
@@ -246,10 +246,10 @@ class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2()
|
||||
field1.writeTo(output)
|
||||
}
|
||||
|
||||
class BuilderLevel1 constructor (field1: Level2 = Level1.Level2.BuilderLevel2().build()) {
|
||||
var field1 : Level2
|
||||
class BuilderLevel1 constructor (field1: Level1.Level2 = Level1.Level2.BuilderLevel2().build()) {
|
||||
var field1 : Level1.Level2
|
||||
private set
|
||||
fun setField1(value: Level2): Level1.BuilderLevel1 {
|
||||
fun setField1(value: Level1.Level2): Level1.BuilderLevel1 {
|
||||
field1 = value
|
||||
return this
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user