Protobuf: fixed stub in name resolving. Now all names are resolved properly; full-qualified access is used in generated code. Added corresponding test

This commit is contained in:
dsavvinov
2016-07-18 19:27:30 +03:00
parent 8552e0b778
commit 519b8e880a
17 changed files with 552 additions and 3140 deletions
@@ -5,6 +5,7 @@ LDFLAGS = -lprotoc -lprotobuf
EXE = protoc
SRCDIR = src
BINDIR = bin
TESTDIR = test
OBJECTS = $(patsubst $(SRCDIR)/%.cc,$(BINDIR)/%.o,$(wildcard $(SRCDIR)/*.cc))
@@ -25,10 +26,6 @@ clean:
rm -rf $(BINDIR) $(EXE)
generate:
./protoc --kotlin_out=./ ./test/addressbook.proto
./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
low: dummy
dummy: CXXFLAGS += -DKOTLIN_GENERATED_CODE_LANGUAGE_LEVEL_LOW
dummy: all
@@ -6,6 +6,7 @@
#include <iostream>
#include "kotlin_enum_generator.h"
#include "kotlin_field_generator.h"
#include "kotlin_name_resolver.h"
#include <algorithm>
namespace google {
@@ -14,6 +15,7 @@ namespace compiler {
namespace kotlin {
class FieldGenerator; // declared in "kotlin_file_generator.h"
class NameResolver; // declared in "kotlin_name_resolver.h"
void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
generateHeader(printer, isBuilder);
@@ -74,26 +76,29 @@ void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
printer->Print("}\n");
}
ClassGenerator::ClassGenerator(Descriptor const *descriptor)
: descriptor(descriptor) {
ClassGenerator::ClassGenerator(Descriptor const *descriptor, NameResolver * nameResolver)
: descriptor(descriptor)
, nameResolver(nameResolver)
{
simpleName = descriptor->name();
builderName = "Builder" + simpleName;
int field_count = descriptor->field_count();
for (int i = 0; i < field_count; ++i) {
FieldDescriptor const * fieldDescriptor = descriptor->field(i);
properties.push_back(new FieldGenerator(fieldDescriptor, /* enclosingClass = */ this));
properties.push_back(new FieldGenerator(fieldDescriptor, /* enclosingClass = */ this, nameResolver));
}
int nested_types_count = descriptor->nested_type_count();
for (int i = 0; i < nested_types_count; ++i) {
Descriptor const * nestedClassDescriptor = descriptor->nested_type(i);
classesDeclarations.push_back(new ClassGenerator(nestedClassDescriptor));
nameResolver->addClass(nestedClassDescriptor->name(), nameResolver->getClassName(simpleName));
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));
enumsDeclaraions.push_back(new EnumGenerator(nestedEnumDescriptor));
}
@@ -165,7 +170,7 @@ void ClassGenerator::generateMergeMethods(io::Printer *printer) const {
printer->Print(vars, "fun mergeFrom (input: CodedInputStream) {\n");
printer->Indent();
vars["builderName"] = builderName;
vars["builderName"] = nameResolver->getBuilderName(simpleName);
printer->Print(vars, "val builder = $builderName$()\n");
printer->Print("mergeWith(builder.parseFrom(input).build())");
@@ -179,7 +184,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 ? builderName : "Unit";
vars["returnType"] = isRead ? nameResolver->getBuilderName(simpleName) : "Unit";
vars["maybeReturn"] = isRead ? "return this\n" : "";
// generate function header
@@ -211,7 +216,7 @@ void ClassGenerator::generateHeader(io::Printer * printer, bool isBuilder) const
}
map<string, string> vars;
vars["name"] = isBuilder? builderName : simpleName;
vars["name"] = isBuilder? "Builder" + simpleName : simpleName;
vars["argumentList"] = argumentList;
vars["maybePrivate"] = isBuilder? "" : " private";
printer->Print(vars,
@@ -261,7 +266,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"] = builderName;
vars["builderName"] = nameResolver->getBuilderName(simpleName);
printer->Print("fun parseFieldFrom(input: CodedInputStream): Boolean {\n");
printer->Indent();
@@ -10,6 +10,7 @@
#include <google/protobuf/descriptor.h>
#include "kotlin_field_generator.h"
#include "kotlin_enum_generator.h"
#include "kotlin_name_resolver.h"
namespace google {
namespace protobuf {
@@ -17,6 +18,7 @@ namespace compiler {
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 {
@@ -35,17 +37,18 @@ public:
class ClassGenerator {
public:
string simpleName;
string fullName;
vector <FieldGenerator *> properties;
vector <ClassGenerator *> classesDeclarations;
vector <EnumGenerator *> enumsDeclaraions;
string builderName;
ClassGenerator (Descriptor const * descriptor);
ClassGenerator (Descriptor const * descriptor, NameResolver * nameResolver);
~ClassGenerator ();
void generateCode (io::Printer * printer, bool isBuilder = false) const;
private:
Descriptor const * descriptor;
NameResolver * nameResolver;
void generateBuilder (io::Printer * printer) const;
void generateBuildMethod (io::Printer * printer) const;
void generateInitSection (io::Printer * printer) const;
@@ -15,12 +15,7 @@ namespace compiler {
namespace kotlin {
string FieldGenerator::getInitValue() const {
if (descriptor->is_repeated())
return "mutableListOf()";
else if (protoType == FieldDescriptor::TYPE_MESSAGE) {
return enclosingClass->builderName + "().build()";
}
return name_resolving::protobufTypeToInitValue(descriptor);
return name_resolving::protobufTypeToInitValue(this);
}
void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
@@ -45,7 +40,7 @@ void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const {
}
}
FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerator const * enclosingClass)
FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerator const * enclosingClass, NameResolver * nameResolver)
: descriptor(descriptor)
, modifier(descriptor->label())
, enclosingClass(enclosingClass)
@@ -54,6 +49,7 @@ FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerato
, fullType(name_resolving::protobufToKotlinField(descriptor))
, protoType(descriptor->type())
, fieldNumber(descriptor->number())
, nameResolver(nameResolver)
{ }
// TODO: long, complicated and messy method. Refactor it ASAP
@@ -94,7 +90,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);
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
/* Another dirty hack here: create tmp variable of a given type and read it from input stream
then add that tmp var into list.
@@ -140,7 +136,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
printer->Indent();
// hack: see above
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass);
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
singleFieldGen.simpleName = "item";
singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL;
@@ -200,7 +196,7 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead
// read message itself without tag
printer->Print(vars,
"$fieldName$.readFrom(input)\n");
"$fieldName$.mergeFrom(input)\n");
// check that actual size equal to expected size
printer->Print(vars, "if (expectedSize != $fieldName$.getSize()) { "
@@ -237,7 +233,7 @@ void FieldGenerator::generateSetter(io::Printer *printer) const {
map <string, string> vars;
vars["camelCaseName"] = name_resolving::makeFirstLetterUpper(simpleName);
vars["fieldName"] = simpleName;
vars["builderName"] = enclosingClass->builderName;
vars["builderName"] = nameResolver->getBuilderName(enclosingClass->simpleName);
vars["type"] = fullType;
printer->Print(vars,
"fun set$camelCaseName$(value: $type$): $builderName$ {\n");
@@ -254,7 +250,7 @@ void FieldGenerator::generateRepeatedMethods(io::Printer * printer, bool isBuild
vars["elementType"] = underlyingType;
vars["arg"] = "value";
vars["fieldName"] = simpleName;
vars["builderName"] = enclosingClass->builderName;
vars["builderName"] = nameResolver->getBuilderName(underlyingType); // TODO: call to non-existent field in map.
// generate indexed setter for builders
if (isBuilder) {
@@ -300,7 +296,7 @@ string FieldGenerator::getUnderlyingTypeInitValue() const {
if (protoType == FieldDescriptor::TYPE_MESSAGE) {
return "Builder" + underlyingType + "().build()";
}
return name_resolving::protobufTypeToInitValue(descriptor);
return name_resolving::protobufTypeToInitValue(this);
}
void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string varName, bool noTag) const {
@@ -325,7 +321,7 @@ void FieldGenerator::generateSizeEstimationCode(io::Printer *printer, string var
printer->Indent();
// hack: reuse generateSizeEstimationCode in the same manner as in generateSerializationCode
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass);
FieldGenerator singleFieldGen = FieldGenerator(descriptor, enclosingClass, nameResolver);
singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL;
singleFieldGen.simpleName = "item";
singleFieldGen.generateSizeEstimationCode(printer, "arraySize");
@@ -9,6 +9,7 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include "kotlin_class_generator.h"
#include "kotlin_name_resolver.h"
namespace google {
namespace protobuf {
@@ -16,11 +17,11 @@ namespace compiler {
namespace kotlin {
class ClassGenerator; // declared in kotlin_class_generator.h
class NameResolver; // declared in kotlin_name_resolver.h
class FieldGenerator {
private:
FieldDescriptor const * descriptor;
// TODO: refactor from field generator to some static utility namespace
void generateSetter(io::Printer * printer) const;
@@ -38,15 +39,18 @@ public:
* 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;
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);
FieldGenerator(FieldDescriptor const * descriptor, ClassGenerator const * enclosingClass, NameResolver * nameResolver);
string getKotlinFunctionSuffix() const;
};
@@ -30,20 +30,26 @@ bool FileGenerator::Generate(const FileDescriptor *file, const string &parameter
string const file_name = name_resolving::getKotlinOutputByProtoName(file->name());
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(file_name));
io::Printer printer(output.get(), '$', /* annotation_collector = */ NULL);
NameResolver * nameResolver = new NameResolver();
// Create Generators for all top-level messages
int topLevelMessagesCount = file->message_type_count();
for (int i = 0; i < topLevelMessagesCount; ++i) {
Descriptor const * descriptor = file->message_type(i);
ClassGenerator * cgen = new ClassGenerator(descriptor);
// 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);
classes.push_back(cgen);
}
// Generate code and clean up
generateCode(&printer, classes);
for (int i = 0; i < classes.size(); ++i) {
delete classes[i];
}
delete nameResolver;
return true;
}
@@ -3,6 +3,7 @@
//
#include "kotlin_name_resolver.h"
#include "kotlin_field_generator.h"
#include <google/protobuf/descriptor.h>
#include <string>
@@ -27,7 +28,8 @@ string getFileNameWithoutExtension(string fullName) {
}
string getKotlinOutputByProtoName(string protoName) {
string justName = getFileNameWithoutExtension(protoName);
string fileWithoutPath = protoName.substr(protoName.find_last_of("/") + 1, protoName.length());
string justName = getFileNameWithoutExtension(fileWithoutPath);
return justName + ".kt";
}
@@ -91,8 +93,12 @@ string protobufToKotlinField(FieldDescriptor const * descriptor) {
}
// TODO: think about nested arrays
string protobufTypeToInitValue(FieldDescriptor const * descriptor) {
FieldDescriptor::Type type = descriptor->type();
string protobufTypeToInitValue(FieldGenerator const * fieldGen) {
if (fieldGen->modifier == FieldDescriptor::LABEL_REPEATED) {
return "mutableListOf()";
}
FieldDescriptor::Type type = fieldGen->protoType;
switch(type) {
case FieldDescriptor::TYPE_BOOL:
return "false";
@@ -101,8 +107,7 @@ string protobufTypeToInitValue(FieldDescriptor const * descriptor) {
case FieldDescriptor::TYPE_DOUBLE:
return "0.0";
case FieldDescriptor::TYPE_ENUM: {
string enumType = descriptor->enum_type()->name();
return enumType + ".fromIntTo" + enumType + "(0)"; // produce enum from 0, as demanded by Google
return fieldGen->nameResolver->getClassName(fieldGen->fullType) + ".fromIntTo" + fieldGen->fullType + "(0)"; // produce enum from 0, as demanded by Google
}
case FieldDescriptor::TYPE_FIXED32:
return "0";
@@ -115,7 +120,7 @@ string protobufTypeToInitValue(FieldDescriptor const * descriptor) {
case FieldDescriptor::TYPE_INT64:
return "0L";
case FieldDescriptor::TYPE_MESSAGE:
return string(descriptor->message_type()->name()) + "()";
return fieldGen->nameResolver->getBuilderName(fieldGen->fullType) + "().build()";
case FieldDescriptor::TYPE_SFIXED32:
return "0";
case FieldDescriptor::TYPE_SFIXED64:
@@ -171,8 +176,36 @@ string protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type) {
return "SInt64";
}
}
} // namespace name_resolving
NameResolver::NameResolver() {
names = map<string, string>();
builders = map<string, string>();
}
void NameResolver::addClass(string simpleName, string parentName) {
if (parentName == "") {
names[simpleName] = simpleName;
builders[simpleName] = simpleName + ".Builder" + simpleName;
}
else
{
names[simpleName] = parentName + "." + simpleName;
builders[simpleName] = parentName + "." + simpleName + ".Builder" + simpleName;
}
}
string NameResolver::getClassName(string simpleName) {
return names[simpleName];
}
string NameResolver::getBuilderName(string classSimpleName) {
return builders[classSimpleName];
}
} // namespace kotlin
} // namespace compiler
} // namespace protobuf
} // namespace google
} // namespace google
@@ -7,11 +7,28 @@
#include <string>
#include <google/protobuf/descriptor.h>
#include <map>
#include "kotlin_field_generator.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace kotlin {
class FieldGenerator; // declared in kotlin_field_generator.h
class ClassGenerator; // declared in kotlin_class_generator.h
class NameResolver {
public:
NameResolver();
void addClass (string simpleName, string parentName);
string getClassName (string simpleName);
string getBuilderName (string classSimpleName);
private:
std::map <string, string> names;
std::map <string, string> builders;
};
namespace name_resolving {
std::string makeFirstLetterUpper(std::string s);
@@ -20,7 +37,7 @@ std::string getFileNameWithoutExtension(std::string fullName);
std::string getKotlinOutputByProtoName(std::string protoName);
std::string protobufTypeToInitValue(FieldDescriptor const * descriptor);
std::string protobufTypeToInitValue(FieldGenerator const * fieldGenerator);
std::string protobufToKotlinField(FieldDescriptor const * descriptor);
@@ -0,0 +1,14 @@
syntax = "proto3";
message Level1 {
Level2 field1 = 1;
message Level2 {
Level3 field2 = 2;
message Level3 {
Level4 field3 = 3;
message Level4 {
string field4 = 4;
}
}
}
}
@@ -1,18 +0,0 @@
class Person {
class PhoneNumber {
val number : kotlin.String?
val type : PhoneType?
}
enum class PhoneType(val ord: Int) {
MOBILE (0),
HOME (1),
WORK (2)
}
val name : kotlin.String?
val id : Int?
val email : kotlin.String?
val phones : List <PhoneNumber>
}
class AddressBook {
val people : List <Person>
}
-451
View File
@@ -1,451 +0,0 @@
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
private set
var id : Int
private set
var email : kotlin.String
private set
var phones : MutableList <PhoneNumber>
private set
var someBytes : ByteArray
private set
init {
this.name = name
this.id = id
this.email = email
this.phones = phones
this.someBytes = someBytes
}
enum class PhoneType(val ord: Int) {
MOBILE (0),
HOME (1),
WORK (2);
companion object {
fun fromIntToPhoneType (ord: Int): PhoneType {
return when (ord) {
0 -> PhoneType.MOBILE
1 -> PhoneType.HOME
2 -> PhoneType.WORK
else -> throw InvalidProtocolBufferException("Error: got unexpected int ${ord} while parsing PhoneType ");
}
}
}
}
class PhoneNumber private constructor (number: kotlin.String = "", type: PhoneType = PhoneType.fromIntToPhoneType(0)) {
var number : kotlin.String
private set
var type : PhoneType
private set
init {
this.number = number
this.type = type
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeString (1, number)
output.writeEnum (2, type.ord)
}
class BuilderPhoneNumber constructor (number: kotlin.String = "", type: PhoneType = PhoneType.fromIntToPhoneType(0)) {
var number : kotlin.String
private set
fun setNumber(value: kotlin.String): BuilderPhoneNumber {
number = value
return this
}
var type : PhoneType
private set
fun setType(value: PhoneType): BuilderPhoneNumber {
type = value
return this
}
init {
this.number = number
this.type = type
}
fun readFrom (input: CodedInputStream): BuilderPhoneNumber {
number = input.readString(1)
type = PhoneType.fromIntToPhoneType(input.readEnum(2))
return this
}
fun build(): PhoneNumber {
return PhoneNumber(number, type)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
1 -> number = input.readStringNoTag()
2 -> type = PhoneType.fromIntToPhoneType(input.readEnumNoTag())
}
return true}
fun parseFrom(input: CodedInputStream): BuilderPhoneNumber {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(1, number)
size += WireFormat.getEnumSize(2, type.ord)
return size
}
}
fun mergeWith (other: PhoneNumber) {
number = other.number
type = other.type
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderPhoneNumber()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(1, number)
size += WireFormat.getEnumSize(2, type.ord)
return size
}
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeString (1, name)
output.writeInt32 (2, id)
output.writeString (3, email)
if (phones.size > 0) {
output.writeTag(4, WireType.LENGTH_DELIMITED)
var arrayByteSize = 0
run {
var arraySize = 0
for (item in phones) {
arraySize += item.getSize() + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
arrayByteSize += arraySize
}
output.writeInt32NoTag(arrayByteSize)
for (item in phones) {
output.writeTag(4, WireType.LENGTH_DELIMITED)
output.writeInt32NoTag(item.getSize())
item.writeTo(output)
}
}
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
private set
fun setName(value: kotlin.String): BuilderPerson {
name = value
return this
}
var id : Int
private set
fun setId(value: Int): BuilderPerson {
id = value
return this
}
var email : kotlin.String
private set
fun setEmail(value: kotlin.String): BuilderPerson {
email = value
return this
}
var phones : MutableList <PhoneNumber>
private set
fun setPhones(value: MutableList <PhoneNumber> ): BuilderPerson {
phones = value
return this
}
fun setPhoneNumber(index: Int, value: PhoneNumber): BuilderPerson {
phones[index] = value
return this
}
fun addPhoneNumber(value: PhoneNumber): BuilderPerson {
phones.add(value)
return this
}
fun addAllPhoneNumber(value: Iterable<PhoneNumber>): BuilderPerson {
for (item in value) {
phones.add(item)
}
return this
}
var someBytes : ByteArray
private set
fun setSomeBytes(value: ByteArray): BuilderPerson {
someBytes = value
return this
}
init {
this.name = name
this.id = id
this.email = email
this.phones = phones
this.someBytes = someBytes
}
fun readFrom (input: CodedInputStream): BuilderPerson {
name = input.readString(1)
id = input.readInt32(2)
email = input.readString(3)
val tag = input.readTag(4, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
var readSize = 0
while(readSize != expectedSize) {
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
input.readTag(4, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(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())
}
someBytes = input.readBytes(5)
return this
}
fun build(): Person {
return Person(name, id, email, phones, someBytes)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
1 -> name = input.readStringNoTag()
2 -> id = input.readInt32NoTag()
3 -> email = input.readStringNoTag()
4 -> {
val expectedSize = input.readInt32NoTag()
var readSize = 0
while(readSize != expectedSize) {
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
input.readTag(4, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(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())
}
}
5 -> someBytes = input.readBytesNoTag()
}
return true}
fun parseFrom(input: CodedInputStream): BuilderPerson {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(1, name)
size += WireFormat.getInt32Size(2, id)
size += WireFormat.getStringSize(3, email)
run {
var arraySize = 0
for (item in phones) {
arraySize += item.getSize() + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
size += arraySize + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
}
size += WireFormat.getBytesSize(5, someBytes)
return size
}
}
fun mergeWith (other: Person) {
name = other.name
id = other.id
email = other.email
phones.addAll(other.phones)
someBytes.plus(other.someBytes)
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderPerson()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(1, name)
size += WireFormat.getInt32Size(2, id)
size += WireFormat.getStringSize(3, email)
run {
var arraySize = 0
for (item in phones) {
arraySize += item.getSize() + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
size += arraySize + WireFormat.getTagSize(4, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
}
size += WireFormat.getBytesSize(5, someBytes)
return size
}
}
class AddressBook private constructor (people: MutableList <Person> = mutableListOf()) {
var people : MutableList <Person>
private set
init {
this.people = people
}
fun writeTo (output: CodedOutputStream): Unit {
if (people.size > 0) {
output.writeTag(1, WireType.LENGTH_DELIMITED)
var arrayByteSize = 0
run {
var arraySize = 0
for (item in people) {
arraySize += item.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
arrayByteSize += arraySize
}
output.writeInt32NoTag(arrayByteSize)
for (item in people) {
output.writeTag(1, WireType.LENGTH_DELIMITED)
output.writeInt32NoTag(item.getSize())
item.writeTo(output)
}
}
}
class BuilderAddressBook constructor (people: MutableList <Person> = mutableListOf()) {
var people : MutableList <Person>
private set
fun setPeople(value: MutableList <Person> ): BuilderAddressBook {
people = value
return this
}
fun setPerson(index: Int, value: Person): BuilderAddressBook {
people[index] = value
return this
}
fun addPerson(value: Person): BuilderAddressBook {
people.add(value)
return this
}
fun addAllPerson(value: Iterable<Person>): BuilderAddressBook {
for (item in value) {
people.add(item)
}
return this
}
init {
this.people = people
}
fun readFrom (input: CodedInputStream): BuilderAddressBook {
val tag = input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
var readSize = 0
while(readSize != expectedSize) {
val tmp: Person.BuilderPerson = Person.BuilderPerson()
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(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())
}
return this
}
fun build(): AddressBook {
return AddressBook(people)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
1 -> {
val expectedSize = input.readInt32NoTag()
var readSize = 0
while(readSize != expectedSize) {
val tmp: Person.BuilderPerson = Person.BuilderPerson()
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(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())
}
}
}
return true}
fun parseFrom(input: CodedInputStream): BuilderAddressBook {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
run {
var arraySize = 0
for (item in people) {
arraySize += item.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
size += arraySize + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
}
return size
}
}
fun mergeWith (other: AddressBook) {
people.addAll(other.people)
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderAddressBook()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
run {
var arraySize = 0
for (item in people) {
arraySize += item.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(item.getSize())
}
size += arraySize + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(arraySize)
}
return size
}
}
+54
View File
@@ -0,0 +1,54 @@
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
/**
* Created by user on 7/8/16.
*/
object AddressbookTests {
fun testMessageSerialization() {
// Messages work only with CodedStream classes, provided by ProtoKot-runtime library.
// One can create CodedStream passing any instance of corresponding Stream from Java's library.
val s = ByteArrayOutputStream()
val outs = CodedOutputStream(s)
// All messages are immutable. Use Builders for creating new messages
val msg = Person.BuilderPerson()
.setEmail("wtf@dasda.com") // all setters return this builder, so you could chain modifiers in LINQ-style
.setId(42)
.setName("John Doe")
.addPhoneNumber(// repeated fields stored as Array<>, so use arrayOf() for creating repeated fields
Person.PhoneNumber.BuilderPhoneNumber()
.setNumber("342143-23423-42")
.setType(Person.PhoneType.HOME)
.build()
)
.addPhoneNumber(
Person.PhoneNumber.BuilderPhoneNumber()
.setNumber("8-800-555-35-35")
.setType(Person.PhoneType.WORK)
.build()
)
.build() // don't forget to call build() to produce message
msg.writeTo(outs)
// Now let's use output stream as input to read our message from it!
var ins = CodedInputStream(ByteArrayInputStream(s.toByteArray()))
// Create default instance of message
var readMsg = Person.BuilderPerson().build()
// Read in that message data from input stream.
readMsg.mergeFrom(ins)
// Note, that currently mergeFrom is the only way to mutate instance of message.
// Don't rely on it, probably mergeFrom will be refactored lately to guarantee full immutability of mesages.
// Better way to read a message:
ins = CodedInputStream(ByteArrayInputStream(s.toByteArray()))
readMsg = Person.BuilderPerson().readFrom(ins).build()
assert(msg == readMsg)
}
}
fun main(args: Array<String>) {
AddressbookTests.testMessageSerialization()
println("OK")
}
-54
View File
@@ -1,54 +0,0 @@
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
/**
* Created by user on 7/8/16.
*/
fun testMessageSerialization() {
// Messages work only with CodedStream classes, provided by ProtoKot-runtime library.
// One can create CodedStream passing any instance of corresponding Stream from Java's library.
val s = ByteArrayOutputStream()
val outs = CodedOutputStream(s)
// All messages are immutable. Use Builders for creating new messages
val msg = Person.BuilderPerson()
.setEmail("wtf@dasda.com") // all setters return this builder, so you could chain modifiers in LINQ-style
.setId(42)
.setName("John Doe")
.addPhoneNumber( // repeated fields stored as Array<>, so use arrayOf() for creating repeated fields
Person.PhoneNumber.BuilderPhoneNumber()
.setNumber("342143-23423-42")
.setType(Person.PhoneType.HOME)
.build()
)
.addPhoneNumber(
Person.PhoneNumber.BuilderPhoneNumber()
.setNumber("8-800-555-35-35")
.setType(Person.PhoneType.WORK)
.build()
)
.build() // don't forget to call build() to produce message
msg.writeTo(outs)
// Now let's use output stream as input to read our message from it!
var ins = CodedInputStream(ByteArrayInputStream(s.toByteArray()))
// Create default instance of message
var readMsg = Person.BuilderPerson().build()
// Read in that message data from input stream.
readMsg.mergeFrom(ins)
// Note, that currently mergeFrom is the only way to mutate instance of message.
// Don't rely on it, probably mergeFrom will be refactored lately to guarantee full immutability of mesages.
// Better way to read a message:
ins = CodedInputStream(ByteArrayInputStream(s.toByteArray()))
readMsg = Person.BuilderPerson().readFrom(ins).build()
assert(msg == readMsg)
}
fun main(args: Array<String>) {
testMessageSerialization()
println("OK")
}
+37
View File
@@ -0,0 +1,37 @@
import java.io.ByteArrayOutputStream
/**
* Created by user on 7/18/16.
*/
object NestedMsgTests {
val msg1 = Level1.BuilderLevel1()
.setField1(
Level1.Level2.BuilderLevel2()
.setField2(
Level1.Level2.Level3.BuilderLevel3()
.setField3(
Level1.Level2.Level3.Level4.BuilderLevel4()
.setField4("Hello!")
.build()
)
.build()
)
.build()
)
.build()
fun testMessageSerialization() {
val s = ByteArrayOutputStream()
val output = CodedOutputStream(s)
msg1.writeTo(output)
val readMsg = Level1.BuilderLevel1().build()
}
}
fun main(args: Array<String>) {
NestedMsgTests.testMessageSerialization()
println("OK")
}
@@ -38,7 +38,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
}
}
}
class PhoneNumber private constructor (number: kotlin.String = "", type: PhoneType = PhoneType.fromIntToPhoneType(0)) {
class PhoneNumber private constructor (number: kotlin.String = "", type: PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
var number : kotlin.String
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 = PhoneType.fromIntToPhoneType(0)) {
class BuilderPhoneNumber constructor (number: kotlin.String = "", type: PhoneType = Person.PhoneType.fromIntToPhoneType(0)) {
var number : kotlin.String
private set
fun setNumber(value: kotlin.String): BuilderPhoneNumber {
fun setNumber(value: kotlin.String): Person.PhoneNumber.BuilderPhoneNumber {
number = value
return this
}
var type : PhoneType
private set
fun setType(value: PhoneType): BuilderPhoneNumber {
fun setType(value: PhoneType): Person.PhoneNumber.BuilderPhoneNumber {
type = value
return this
}
@@ -77,7 +77,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
this.type = type
}
fun readFrom (input: CodedInputStream): BuilderPhoneNumber {
fun readFrom (input: CodedInputStream): Person.PhoneNumber.BuilderPhoneNumber {
number = input.readString(1)
type = PhoneType.fromIntToPhoneType(input.readEnum(2))
return this
@@ -98,7 +98,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
2 -> type = PhoneType.fromIntToPhoneType(input.readEnumNoTag())
}
return true}
fun parseFrom(input: CodedInputStream): BuilderPhoneNumber {
fun parseFrom(input: CodedInputStream): Person.PhoneNumber.BuilderPhoneNumber {
while(parseFieldFrom(input)) {}
return this
}
@@ -117,7 +117,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderPhoneNumber()
val builder = Person.PhoneNumber.BuilderPhoneNumber()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
@@ -155,40 +155,40 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
class BuilderPerson constructor (name: kotlin.String = "", id: Int = 0, email: kotlin.String = "", phones: MutableList <PhoneNumber> = mutableListOf(), someBytes: ByteArray = ByteArray(0)) {
var name : kotlin.String
private set
fun setName(value: kotlin.String): BuilderPerson {
fun setName(value: kotlin.String): Person.BuilderPerson {
name = value
return this
}
var id : Int
private set
fun setId(value: Int): BuilderPerson {
fun setId(value: Int): Person.BuilderPerson {
id = value
return this
}
var email : kotlin.String
private set
fun setEmail(value: kotlin.String): BuilderPerson {
fun setEmail(value: kotlin.String): Person.BuilderPerson {
email = value
return this
}
var phones : MutableList <PhoneNumber>
private set
fun setPhones(value: MutableList <PhoneNumber> ): BuilderPerson {
fun setPhones(value: MutableList <PhoneNumber> ): Person.BuilderPerson {
phones = value
return this
}
fun setPhoneNumber(index: Int, value: PhoneNumber): BuilderPerson {
fun setPhoneNumber(index: Int, value: PhoneNumber): Person.PhoneNumber.BuilderPhoneNumber {
phones[index] = value
return this
}
fun addPhoneNumber(value: PhoneNumber): BuilderPerson {
fun addPhoneNumber(value: PhoneNumber): Person.PhoneNumber.BuilderPhoneNumber {
phones.add(value)
return this
}
fun addAllPhoneNumber(value: Iterable<PhoneNumber>): BuilderPerson {
fun addAllPhoneNumber(value: Iterable<PhoneNumber>): Person.PhoneNumber.BuilderPhoneNumber {
for (item in value) {
phones.add(item)
}
@@ -197,7 +197,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
var someBytes : ByteArray
private set
fun setSomeBytes(value: ByteArray): BuilderPerson {
fun setSomeBytes(value: ByteArray): Person.BuilderPerson {
someBytes = value
return this
}
@@ -211,7 +211,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
this.someBytes = someBytes
}
fun readFrom (input: CodedInputStream): BuilderPerson {
fun readFrom (input: CodedInputStream): Person.BuilderPerson {
name = input.readString(1)
id = input.readInt32(2)
email = input.readString(3)
@@ -222,7 +222,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
input.readTag(4, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(input)
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())
@@ -252,7 +252,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
val tmp: PhoneNumber.BuilderPhoneNumber = PhoneNumber.BuilderPhoneNumber()
input.readTag(4, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(input)
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())
@@ -261,7 +261,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
5 -> someBytes = input.readBytesNoTag()
}
return true}
fun parseFrom(input: CodedInputStream): BuilderPerson {
fun parseFrom(input: CodedInputStream): Person.BuilderPerson {
while(parseFieldFrom(input)) {}
return this
}
@@ -292,7 +292,7 @@ class Person private constructor (name: kotlin.String = "", id: Int = 0, email:
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderPerson()
val builder = Person.BuilderPerson()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
@@ -344,19 +344,19 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
class BuilderAddressBook constructor (people: MutableList <Person> = mutableListOf()) {
var people : MutableList <Person>
private set
fun setPeople(value: MutableList <Person> ): BuilderAddressBook {
fun setPeople(value: MutableList <Person> ): AddressBook.BuilderAddressBook {
people = value
return this
}
fun setPerson(index: Int, value: Person): BuilderAddressBook {
fun setPerson(index: Int, value: Person): Person.BuilderPerson {
people[index] = value
return this
}
fun addPerson(value: Person): BuilderAddressBook {
fun addPerson(value: Person): Person.BuilderPerson {
people.add(value)
return this
}
fun addAllPerson(value: Iterable<Person>): BuilderAddressBook {
fun addAllPerson(value: Iterable<Person>): Person.BuilderPerson {
for (item in value) {
people.add(item)
}
@@ -368,7 +368,7 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
this.people = people
}
fun readFrom (input: CodedInputStream): BuilderAddressBook {
fun readFrom (input: CodedInputStream): AddressBook.BuilderAddressBook {
val tag = input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
var readSize = 0
@@ -376,7 +376,7 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
val tmp: Person.BuilderPerson = Person.BuilderPerson()
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(input)
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())
@@ -402,7 +402,7 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
val tmp: Person.BuilderPerson = Person.BuilderPerson()
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
tmp.readFrom(input)
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())
@@ -410,7 +410,7 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
}
}
return true}
fun parseFrom(input: CodedInputStream): BuilderAddressBook {
fun parseFrom(input: CodedInputStream): AddressBook.BuilderAddressBook {
while(parseFieldFrom(input)) {}
return this
}
@@ -433,7 +433,7 @@ class AddressBook private constructor (people: MutableList <Person> = mutableLi
}
fun mergeFrom (input: CodedInputStream) {
val builder = BuilderAddressBook()
val builder = AddressBook.BuilderAddressBook()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
+315
View File
@@ -0,0 +1,315 @@
class Level1 private constructor (field1: Level2 = Level1.Level2.BuilderLevel2().build()) {
var field1 : Level2
private set
init {
this.field1 = field1
}
class Level2 private constructor (field2: Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
var field2 : Level3
private set
init {
this.field2 = field2
}
class Level3 private constructor (field3: Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
var field3 : Level4
private set
init {
this.field3 = field3
}
class Level4 private constructor (field4: kotlin.String = "") {
var field4 : kotlin.String
private set
init {
this.field4 = field4
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeString (4, field4)
}
class BuilderLevel4 constructor (field4: kotlin.String = "") {
var field4 : kotlin.String
private set
fun setField4(value: kotlin.String): Level1.Level2.Level3.Level4.BuilderLevel4 {
field4 = value
return this
}
init {
this.field4 = field4
}
fun readFrom (input: CodedInputStream): Level1.Level2.Level3.Level4.BuilderLevel4 {
field4 = input.readString(4)
return this
}
fun build(): Level4 {
return Level4(field4)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
4 -> field4 = input.readStringNoTag()
}
return true}
fun parseFrom(input: CodedInputStream): Level1.Level2.Level3.Level4.BuilderLevel4 {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(4, field4)
return size
}
}
fun mergeWith (other: Level4) {
field4 = other.field4
}
fun mergeFrom (input: CodedInputStream) {
val builder = Level1.Level2.Level3.Level4.BuilderLevel4()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += WireFormat.getStringSize(4, field4)
return size
}
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeTag(3, WireType.LENGTH_DELIMITED)
output.writeInt32NoTag(field3.getSize())
field3.writeTo(output)
}
class BuilderLevel3 constructor (field3: Level4 = Level1.Level2.Level3.Level4.BuilderLevel4().build()) {
var field3 : Level4
private set
fun setField3(value: Level4): Level1.Level2.Level3.BuilderLevel3 {
field3 = value
return this
}
init {
this.field3 = field3
}
fun readFrom (input: CodedInputStream): Level1.Level2.Level3.BuilderLevel3 {
input.readTag(3, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field3.mergeFrom(input)
if (expectedSize != field3.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field3.getSize()}") }
return this
}
fun build(): Level3 {
return Level3(field3)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
3 -> {
input.readTag(3, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field3.mergeFrom(input)
if (expectedSize != field3.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field3.getSize()}") }
}
}
return true}
fun parseFrom(input: CodedInputStream): Level1.Level2.Level3.BuilderLevel3 {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += field3.getSize() + WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field3.getSize())
return size
}
}
fun mergeWith (other: Level3) {
field3 = other.field3
}
fun mergeFrom (input: CodedInputStream) {
val builder = Level1.Level2.Level3.BuilderLevel3()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += field3.getSize() + WireFormat.getTagSize(3, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field3.getSize())
return size
}
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeTag(2, WireType.LENGTH_DELIMITED)
output.writeInt32NoTag(field2.getSize())
field2.writeTo(output)
}
class BuilderLevel2 constructor (field2: Level3 = Level1.Level2.Level3.BuilderLevel3().build()) {
var field2 : Level3
private set
fun setField2(value: Level3): Level1.Level2.BuilderLevel2 {
field2 = value
return this
}
init {
this.field2 = field2
}
fun readFrom (input: CodedInputStream): Level1.Level2.BuilderLevel2 {
input.readTag(2, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field2.mergeFrom(input)
if (expectedSize != field2.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field2.getSize()}") }
return this
}
fun build(): Level2 {
return Level2(field2)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
2 -> {
input.readTag(2, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field2.mergeFrom(input)
if (expectedSize != field2.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field2.getSize()}") }
}
}
return true}
fun parseFrom(input: CodedInputStream): Level1.Level2.BuilderLevel2 {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += field2.getSize() + WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field2.getSize())
return size
}
}
fun mergeWith (other: Level2) {
field2 = other.field2
}
fun mergeFrom (input: CodedInputStream) {
val builder = Level1.Level2.BuilderLevel2()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += field2.getSize() + WireFormat.getTagSize(2, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field2.getSize())
return size
}
}
fun writeTo (output: CodedOutputStream): Unit {
output.writeTag(1, WireType.LENGTH_DELIMITED)
output.writeInt32NoTag(field1.getSize())
field1.writeTo(output)
}
class BuilderLevel1 constructor (field1: Level2 = Level1.Level2.BuilderLevel2().build()) {
var field1 : Level2
private set
fun setField1(value: Level2): Level1.BuilderLevel1 {
field1 = value
return this
}
init {
this.field1 = field1
}
fun readFrom (input: CodedInputStream): Level1.BuilderLevel1 {
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field1.mergeFrom(input)
if (expectedSize != field1.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field1.getSize()}") }
return this
}
fun build(): Level1 {
return Level1(field1)
}
fun parseFieldFrom(input: CodedInputStream): Boolean {
if (input.isAtEnd()) { return false }
val tag = input.readInt32NoTag()
if (tag == 0) { return false }
val fieldNumber = WireFormat.getTagFieldNumber(tag)
val wireType = WireFormat.getTagWireType(tag)
when(fieldNumber) {
1 -> {
input.readTag(1, WireType.LENGTH_DELIMITED)
val expectedSize = input.readInt32NoTag()
field1.mergeFrom(input)
if (expectedSize != field1.getSize()) { throw InvalidProtocolBufferException ("Expected size ${expectedSize} got ${field1.getSize()}") }
}
}
return true}
fun parseFrom(input: CodedInputStream): Level1.BuilderLevel1 {
while(parseFieldFrom(input)) {}
return this
}
fun getSize(): Int {
var size = 0
size += field1.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field1.getSize())
return size
}
}
fun mergeWith (other: Level1) {
field1 = other.field1
}
fun mergeFrom (input: CodedInputStream) {
val builder = Level1.BuilderLevel1()
mergeWith(builder.parseFrom(input).build())}
fun getSize(): Int {
var size = 0
size += field1.getSize() + WireFormat.getTagSize(1, WireType.LENGTH_DELIMITED) + WireFormat.getVarint32Size(field1.getSize())
return size
}
}