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:
@@ -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
|
||||
+14
-9
@@ -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();
|
||||
|
||||
+5
-2
@@ -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;
|
||||
|
||||
+10
-14
@@ -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");
|
||||
|
||||
+6
-2
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
+7
-1
@@ -30,20 +30,26 @@ bool FileGenerator::Generate(const FileDescriptor *file, const string ¶meter
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+40
-7
@@ -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
|
||||
|
||||
|
||||
+18
-1
@@ -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);
|
||||
|
||||
|
||||
-2546
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
+29
-29
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user