From cf4cb7556dae0c6b0ad21c5cefd8145fa6b37dda Mon Sep 17 00:00:00 2001 From: dsavvinov <45yadjlzti> Date: Wed, 13 Jul 2016 19:40:59 +0300 Subject: [PATCH] Supported nested messages, repeated fields in Proto compiler. Fixed Kotin runtime appropriately. --- .../kotlin/src/kotlin_class_generator.cc | 207 +- .../kotlin/src/kotlin_class_generator.h | 24 +- .../kotlin/src/kotlin_enum_generator.cc | 46 + .../kotlin/src/kotlin_enum_generator.h | 3 + .../kotlin/src/kotlin_field_generator.cc | 168 +- .../kotlin/src/kotlin_field_generator.h | 15 +- .../compiler/kotlin/test/addressbook.kt | 220 +- .../example/tutorial/AddressBookProtos.java | 2546 +++++++++++++++++ .../kotlin/test/test/addressbook.proto | 18 + proto/compiler/src/AddressBook.kt | 62 + proto/compiler/src/CodedInputStream.kt | 121 +- proto/compiler/src/CodedOutputStream.kt | 141 +- proto/compiler/src/Message.kt | 1 - proto/compiler/src/Person.kt | 158 + proto/compiler/src/TestMessages.kt | 14 +- 15 files changed, 3588 insertions(+), 156 deletions(-) create mode 100644 proto/compiler/google/protobuf/compiler/kotlin/test/com/example/tutorial/AddressBookProtos.java create mode 100644 proto/compiler/google/protobuf/compiler/kotlin/test/test/addressbook.proto create mode 100644 proto/compiler/src/AddressBook.kt create mode 100644 proto/compiler/src/Person.kt diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc index 3d6606cc4df..2b1bb5cc57f 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc @@ -13,53 +13,62 @@ namespace compiler { namespace kotlin { void ClassGenerator::generateCode(io::Printer *printer, bool isBuilder) const { - // print class header - map vars; - vars["modifier"] = modifier.getName(); - vars["name"] = (isBuilder? "Builder" : "") + simpleName; - printer->Print(vars, - "$modifier$ $name$ private constructor () {" - "\n" - ); + generateHeader(printer, isBuilder); printer->Indent(); - // generate code for nested classes declarations - for (ClassGenerator *gen: classesDeclarations) { - gen->generateCode(printer, isBuilder); - printer->Print("\n\n"); // separate each definition from next code block with empty line - } - - // generate code for nested enums declarations - for (EnumGenerator *gen: enumsDeclaraions) { - gen->generateCode(printer); - printer->Print("\n\n"); // separate each definitions from next code block with empty line - } - - // generate code for fields + /** + * Field generator should know if it is generating code for builder. + * or for fair class to choose between 'val' and 'var'. + */ for (FieldGenerator *gen: properties) { - gen->generateCode(printer); + gen->generateCode(printer, isBuilder); printer->Print("\n"); } - // generate constructor for builders - if (isBuilder) { - printer->Print("\n"); - generateConstructor(printer); + printer->Print("\n"); + generateInitSection(printer); + + // enum declarations and nested classes declarations only for fair classes + if (!isBuilder) { + for (EnumGenerator *gen: enumsDeclaraions) { + gen->generateCode(printer); + printer->Print("\n"); + } + + for (ClassGenerator *gen: classesDeclarations) { + gen->generateCode(printer); + printer->Print("\n"); + } } - // generate builder for fair classes + // write serialization methods only for fair classes, read methods only for Builders) + printer->Print("\n"); + generateSerializers(printer, /* isRead = */ isBuilder); + printer->Print("\n"); + generateSerializersNoTag(printer, /* isRead = */ isBuilder); + + // builder and mergeFrom only for fair classes if (!isBuilder) { printer->Print("\n"); generateBuilder(printer); + + printer->Print("\n"); + generateMergeFrom(printer); + } + + // build() is only for builders + if (isBuilder) { + printer->Print("\n"); + generateBuildMethod(printer); } printer->Outdent(); - printer->Print("}"); + printer->Print("}\n"); } -ClassGenerator::ClassGenerator(Descriptor const *descriptor) { +ClassGenerator::ClassGenerator(Descriptor const *descriptor) + : descriptor(descriptor) { simpleName = descriptor->name(); // TODO: think about more careful class naming - modifier = ClassModifier(ClassModifier::CLASS); int field_count = descriptor->field_count(); for (int i = 0; i < field_count; ++i) { @@ -96,52 +105,124 @@ ClassGenerator::~ClassGenerator() { } } -void ClassGenerator::generateBuilder(io::Printer *) const { - +void ClassGenerator::generateBuilder(io::Printer * printer) const { + //XXX: just reuse generateCode with flag isBuilder set + generateCode(printer, /* isBuilder = */ true); } -void ClassGenerator::generateConstructor(io::Printer *printer, bool isBuilder) const { - // generate header - printer->Print("private constructor(\n"); +void ClassGenerator::generateMergeFrom(io::Printer * printer) const { + //TODO: Looks pretty dirty. Should reconsider process of generating readFrom, mergeFrom and writeTo. + map vars; + printer->Print(vars, "fun mergeFrom (input: CodedInputStream) {\n"); + printer->Indent(); - // place each argument of constructor in separate line for a prettier code - // we indent twice to make arguments indentation larger than indentation of inner block - printer->Indent(); - printer->Indent(); for (int i = 0; i < properties.size(); ++i) { - // generate argument definition - map vars; - vars["name"] = properties[i] ->simpleName; - vars["field"] = properties[i]->fieldName; - printer->Print(vars, - "$name$: $field$"); - - // if it's last property, then print closing bracket for argument list, otherwise put comma - if (i + 1 == properties.size()) { - printer->Print(") : this()\n"); - printer->Outdent(); - printer->Outdent(); - printer->Print("{"); - printer->Indent(); - } - else { - printer->Print(","); - } - - printer->Print("\n"); + properties[i]->generateSerializationCode(printer, /* isRead = */ true); } - // print body of constructor - just assign arguments to corresponding fields + printer->Outdent(); + printer->Print("}\n"); +} + +void ClassGenerator::generateSerializers(io::Printer * printer, bool isRead) const { + map vars; + vars["funName"]= isRead ? "readFrom" : "writeTo"; + vars["stream"] = isRead ? "CodedInputStream" : "CodedOutputStream"; + vars["arg"] = isRead ? "input" : "output"; + vars["maybeSeparator"] = isRead ? "" : ", "; + + // generate function header + printer->Print(vars, + "fun $funName$ ($arg$: $stream$) {" + "\n"); + printer->Indent(); + + //TODO: write message tag and size + printer->Print(vars, "$funName$NoTag($arg$)\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void ClassGenerator::generateSerializersNoTag(io::Printer *printer, bool isRead) const { + map vars; + vars["funName"]= isRead ? "readFromNoTag" : "writeToNoTag"; + vars["stream"] = isRead ? "CodedInputStream" : "CodedOutputStream"; + vars["arg"] = isRead ? "input" : "output"; + + // generate function header + printer->Print(vars, + "fun $funName$ ($arg$: $stream$) {" + "\n"); + printer->Indent(); + + // generate code for serialization/deserialization of fields + for (int i = 0; i < properties.size(); ++i) { + properties[i]->generateSerializationCode(printer, isRead); + } + + printer->Outdent(); + printer->Print("}\n"); +} + + + +void ClassGenerator::generateHeader(io::Printer * printer, bool isBuilder) const { + // build list of arguments like 'field1: Type1, field2: Type2, ... ' + string argumentList = ""; + for (int i = 0; i < properties.size(); ++i) { + argumentList += properties[i]->simpleName + ": " + properties[i]->fieldName; + if (i + 1 != properties.size()) { + argumentList += ", "; + } + } + + map vars; + vars["name"] = (isBuilder? "Builder" : "") + simpleName; + vars["argumentList"] = argumentList; + vars["maybePrivate"] = isBuilder? "" : " private"; + printer->Print(vars, + "class $name$$maybePrivate$ constructor ($argumentList$) {" + "\n" + ); +} + +void ClassGenerator::generateBuildMethod(io::Printer * printer) const { + map vars; + vars["returnType"] = simpleName; + printer->Print(vars, + "fun build(): $returnType$ {\n"); + printer->Indent(); + + // pass all fields to constructor of enclosing class + printer->Print(vars, + "return $returnType$("); + for (int i = 0; i < properties.size(); ++i) { + printer->Print(properties[i]->simpleName.c_str()); + if (i + 1 != properties.size()) { + printer->Print(", "); + } + } + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void ClassGenerator::generateInitSection(io::Printer * printer) const { + printer->Print("init {\n"); + printer->Indent(); + for (int i = 0; i < properties.size(); ++i) { map vars; vars["name"] = properties[i]->simpleName; printer->Print(vars, - "this.$name$ = $name$" - "\n" + "this.$name$ = $name$" + "\n" ); } + printer->Outdent(); - printer->Print("}"); + printer->Print("}\n"); } diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.h b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.h index 732f546f792..adcfac50453 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.h +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_class_generator.h @@ -32,7 +32,6 @@ public: class ClassGenerator { public: - ClassModifier modifier; string simpleName; vector properties; vector classesDeclarations; @@ -41,15 +40,30 @@ public: ClassGenerator (Descriptor const * descriptor); ~ClassGenerator (); + + void generateCode (io::Printer * printer, bool isBuilder = false) const; +private: + Descriptor const * descriptor; + void generateBuilder (io::Printer * printer) const; + void generateBuildMethod (io::Printer * printer) const; + void generateInitSection (io::Printer * printer) const; + /** * Flag isBuilder used for reducing code repeating, as code for class itself * and for its inner builder are structurally very alike and can be generated * with very little differences (like changing 'val's to 'var's and etc.) */ - void generateCode (io::Printer * printer, bool isBuilder = false) const; -private: - void generateBuilder (io::Printer * printer) const; - void generateConstructor(io::Printer * printer, bool isBuilder = false) const; + void generateHeader(io::Printer * printer, bool isBuilder = false) const; + + /** + * IsRead flag indicates that readFrom method should be generated, otherwise + * writeTo method is generated. Motivation is similar to the isBuilder flag: + * both methods are structurally the same with some trivial substitutions + * (read -> write and etc.) + */ + void generateSerializersNoTag(io::Printer *printer, bool isRead = false) const; + void generateSerializers(io::Printer * printer, bool isRead = false) const; + void generateMergeFrom(io::Printer * printer) const; }; } // namespace kotlin diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.cc b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.cc index 3af18d2a6d5..1f976e31025 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.cc +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.cc @@ -47,12 +47,58 @@ void EnumGenerator::generateCode(io::Printer * printer) const { if (i + 1 != enumValues.size()) { printer->Print(","); } + else { + printer->Print(";"); // semicolon is necessary as companion object will follow + } printer->Print("\n"); } + + printer->Print("\n"); + gemerateEnumConverters(printer); + printer->Outdent(); printer->Print("}"); } +void EnumGenerator::gemerateEnumConverters(io::Printer *printer) const { + map vars; + vars["dollar"] = "$"; + vars["type"] = simpleName; + + printer->Print("companion object {\n"); + printer->Indent(); + + printer->Print(vars, "fun fromIntTo$type$ (ord: Int): $type$ {\n"); + printer->Indent(); + + printer->Print("return when (ord) {\n"); + printer->Indent(); + + // map ints to enum values + for (int j = 0; j < enumValues.size(); ++j) { + vars["ordinal"] = std::to_string(enumValues[j]->ordinal); + vars["value"] = enumValues[j]->simpleName; + + printer->Print(vars, + "$ordinal$ -> $type$.$value$\n"); + } + + // catch cast errors in else-clause + printer->Print(vars, + "else -> throw InvalidProtocolBufferException(" + "\"Error: got unexpected int $dollar${ord} while parsing $type$ \"" + ");\n"); + + printer->Outdent(); // when-clause + printer->Print("}\n"); + + printer->Outdent(); // function body + printer->Print("}\n"); + + printer->Outdent(); // companion object body + printer->Print("}\n"); +} + EnumGenerator::~EnumGenerator() { for (int i = 0; i < enumValues.size(); ++i) { delete enumValues[i]; diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.h b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.h index aa6d058a579..3265777a488 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.h +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_enum_generator.h @@ -30,6 +30,9 @@ public: vector enumValues; void generateCode(io::Printer *) const; + +private: + void gemerateEnumConverters(io::Printer *printer) const; }; } // namespace kotlin diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc index 6d57c4294a8..2fbdea90979 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc @@ -28,7 +28,7 @@ string FieldGenerator::protobufToKotlinField() const { postamble = "?"; break; case FieldDescriptor::LABEL_REPEATED: - preamble = "List <"; + preamble = "Array <"; postamble = "> "; break; } @@ -90,16 +90,18 @@ string FieldGenerator::getInitValue() const { return fieldName + "()"; } -void FieldGenerator::generateCode(io::Printer *printer) const { - /** Generate Kotlin-code for field. - * Note that we use 'val' everywhere, as we want messages to be immutable. - * For constructing Messages corresponding Builders should be used. - */ +void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const { map vars; vars["name"] = simpleName; vars["field"] = protobufToKotlinField(); - vars["initValue"] = initValue; - printer->Print(vars, "val $name$ : $field$ = $initValue$"); + printer->Print(vars, "var $name$ : $field$\n"); + + // make setter private for fair classes + if (!isBuilder) { + printer->Indent(); + printer->Print("private set\n"); + printer->Outdent(); + } } FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor) @@ -107,9 +109,159 @@ FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor) , modifier(descriptor->label()) , simpleName(descriptor->name()) , fieldName(protobufToKotlinField()) + , fieldType(protobufToKotlinType()) , initValue(getInitValue()) { } +void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead, bool noTag) const { + map vars; + vars["type"] = protobufTypeToKotlinFunctionSuffix(descriptor->type()); + vars["fieldNumber"] = std::to_string(descriptor->number()); + vars["fieldName"] = simpleName; + vars["arg"] = isRead ? "input" : "output"; + + /** + * First of all, try to generate syntax for repeated fields because it's separate case. + * Do this according to protobuf format: + * - Check if size of array is > 0, because empty repeated fields shouldn't appear in message + * - Write tag explicitly + * - Write length as int32 (note that tag shouldn't be added) + * - Write all repeated elements via recursive call + */ + if (modifier == FieldDescriptor::LABEL_REPEATED) { + printer->Print(vars, "if ($fieldName$.size > 0) {\n"); + printer->Indent(); + + // tag + if (isRead) { + //TODO: dirty stub here! Normally, reading from input should be delegated to Parsers, with proper error handling and etc. + //Currently tag is ignored, and fields order is critical for serialization/deserialization. Therefore, + //backward-compability and extensions are not supported. + printer->Print(vars, "val tag = input.readTag()\n"); + printer->Print(vars, "val listSize = input.readInt32NoTag()\n"); + printer->Print(vars, "for (i in 1..listSize) {\n"); + printer->Indent(); + printer->Print(vars, "$fieldName$[i - 1].mergeFrom(input)\n"); + printer->Outdent(); + printer->Print("}\n"); + } + else { + // length + printer->Print(vars, "$arg$.writeInt32NoTag($fieldName$.size)\n"); + + // all elements + printer->Print(vars, "for (item in $fieldName$) {\n"); + printer->Indent(); + + /* hack: copy current FieldGenerator and change label to OPTIONAL. This will allow + to re-use this function for generating serialization code for elements of array. + More importantly, this will care about nested types too. + However, this hack isn't necessary and could be safely removed as soon as target + code will support inheritance and interfaces + (then writing CodedOutputStream.writeMessage will be possible). + */ + FieldGenerator singleFieldGen = FieldGenerator(descriptor); + singleFieldGen.modifier = FieldDescriptor::LABEL_OPTIONAL; + singleFieldGen.generateSerializationCode(printer, isRead, /* noTag = */ true); + + printer->Outdent(); // for-loop + printer->Print("}\n"); + } + + printer->Outdent(); // if-clause + printer->Print("}\n"); + + return; + } + + /* + Then check for conversions 'int -> enum-value' and \enum-value -> int' if current + field is enum. + This is necessary, because CodedStream stores enums as Ints in wire, delegating + responsibility for casting those Ints to enum values and vice versa to the caller. + Example: enumField = fromIntToMyEnumName(input.readEnum(42)) + Example: output.writeEnum(42, enumField.ord) + */ + if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { + vars["converter"] = fieldType + ".fromIntTo" + fieldType; + if (isRead) { + printer->Print(vars, "$fieldName$ = $converter$(input.read$type$($fieldNumber$))\n"); + } + else { + printer->Print(vars, "output.write$type$ ($fieldNumber$, $fieldName$?.ord)\n"); + } + return; + } + + /* + Then check for nested messages. Then we re-use writeTo method, that should be defined in + that message + */ + if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) { + vars["fieldName"] = noTag ? "item" : simpleName; + vars["maybeNoTag"] = noTag ? "NoTag" : ""; + if (isRead) { + printer->Print(vars, "$fieldName$.readFrom$maybeNoTag$(input)\n"); + } + else { + printer->Print(vars, "$fieldName$.writeTo$maybeNoTag$(output)\n"); + } + return; + } + + /* Finally, serialize trivial cases */ + if (isRead) { + printer->Print(vars, "$fieldName$ = input.read$type$($fieldNumber$)\n"); + } + else { + printer->Print(vars, "output.write$type$ ($fieldNumber$, $fieldName$)\n"); + } + + + // TODO: support tricky types like enums/messages/repeated fields/etc +} + +// TODO: think about refactoring this method to FieldGenerator, as it is related to field, not to Class in general +string FieldGenerator::protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type) const { + switch (type) { + case FieldDescriptor::TYPE_DOUBLE: + return "Double"; + case FieldDescriptor::TYPE_FLOAT: + return "Float"; + case FieldDescriptor::TYPE_INT64: + return "Int64"; + case FieldDescriptor::TYPE_UINT64: + return "UInt64"; + case FieldDescriptor::TYPE_INT32: + return "Int32"; + case FieldDescriptor::TYPE_FIXED64: + return "Fixed64"; + case FieldDescriptor::TYPE_FIXED32: + return "Fixed32"; + case FieldDescriptor::TYPE_BOOL: + return "Bool"; + case FieldDescriptor::TYPE_STRING: + return "String"; + case FieldDescriptor::TYPE_GROUP: + return ""; // deprecated // TODO: think about proper error handling here + case FieldDescriptor::TYPE_MESSAGE: + return "Message"; // TODO: support messages + case FieldDescriptor::TYPE_BYTES: + return ""; // TODO: support bytes + case FieldDescriptor::TYPE_UINT32: + return "UInt32"; + case FieldDescriptor::TYPE_ENUM: + return "Enum"; + case FieldDescriptor::TYPE_SFIXED32: + return "SFixed32"; + case FieldDescriptor::TYPE_SFIXED64: + return "SFixed64"; + case FieldDescriptor::TYPE_SINT32: + return "SInt32"; + case FieldDescriptor::TYPE_SINT64: + return "SInt64"; + } +} } // namespace kotlin } // namspace compiler } // namespace protobuf diff --git a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h index ebdf8f12f37..4859bef0a3d 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h +++ b/proto/compiler/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h @@ -21,13 +21,24 @@ private: string protobufToKotlinType () const; string getInitValue() const; + /** + * Converts one of protobuf wire types to corresponding Kotlin type with proper + * naming, so it could be used as suffix after read/write, resulting in function + * in CodedInputStream/CodedOutputStream. + * Example: protobufToKotlinFunctionSuffix(TYPE_SFIXED32) returns "SFixed32", and + * in Kotlin runtime exists method + * CodedInputStream.readSFixed32(fieldNumber: Int) + */ + string protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type) const; + public: FieldDescriptor::Label modifier; string simpleName; string fieldName; + string fieldType; string initValue; - - void generateCode(io::Printer *) const; + void generateCode(io::Printer * printer, bool isBuilder = false) const; + void generateSerializationCode(io::Printer * printer, bool isRead = false, bool noTag = false) const; FieldGenerator(FieldDescriptor const * descriptor); }; diff --git a/proto/compiler/google/protobuf/compiler/kotlin/test/addressbook.kt b/proto/compiler/google/protobuf/compiler/kotlin/test/addressbook.kt index e12d845444d..8a930e848c9 100644 --- a/proto/compiler/google/protobuf/compiler/kotlin/test/addressbook.kt +++ b/proto/compiler/google/protobuf/compiler/kotlin/test/addressbook.kt @@ -1,25 +1,221 @@ -class Person private constructor () { - class PhoneNumber private constructor () { - val number : kotlin.String? = null - val type : PhoneType? = null +class Person private constructor (name: kotlin.String?, id: Int?, email: kotlin.String?, phones: Array ) { + var name : kotlin.String? + private set + var id : Int? + private set + + var email : kotlin.String? + private set + + var phones : Array + private set + + + init { + this.name = name + this.id = id + this.email = email + this.phones = phones } - enum class PhoneType(val ord: Int) { MOBILE (0), HOME (1), - WORK (2) + 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?) { + var number : kotlin.String? + private set + + var type : PhoneType? + private set + + + init { + this.number = number + this.type = type + } + + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + output.writeString (1, number) + output.writeEnum (2, type?.ord) + } + + class BuilderPhoneNumber constructor (number: kotlin.String?, type: PhoneType?) { + var number : kotlin.String? + + var type : PhoneType? + + + init { + this.number = number + this.type = type + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + number = input.readString(1) + type = PhoneType.fromIntToPhoneType(input.readEnum(2)) + } + + fun build(): PhoneNumber { + return PhoneNumber(number, type) + } + } + + fun mergeFrom (input: CodedInputStream) { + number = input.readString(1) + type = PhoneType.fromIntToPhoneType(input.readEnum(2)) + } } - val name : kotlin.String? = null - val id : Int? = null - val email : kotlin.String? = null - val phones : List = listOf() + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + output.writeString (1, name) + output.writeInt32 (2, id) + output.writeString (3, email) + if (phones.size > 0) { + output.writeInt32NoTag(phones.size) + for (item in phones) { + item.writeToNoTag(output) + } + } + } + + class BuilderPerson constructor (name: kotlin.String?, id: Int?, email: kotlin.String?, phones: Array ) { + var name : kotlin.String? + + var id : Int? + + var email : kotlin.String? + + var phones : Array + + + init { + this.name = name + this.id = id + this.email = email + this.phones = phones + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + name = input.readString(1) + id = input.readInt32(2) + email = input.readString(3) + if (phones.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + phones[i - 1].mergeFrom(input) + } + } + } + + fun build(): Person { + return Person(name, id, email, phones) + } + } + + fun mergeFrom (input: CodedInputStream) { + name = input.readString(1) + id = input.readInt32(2) + email = input.readString(3) + if (phones.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + phones[i - 1].mergeFrom(input) + } + } + } } -class AddressBook private constructor () { - val people : List = listOf() +class AddressBook private constructor (people: Array ) { + var people : Array + private set + + + init { + this.people = people + } + + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + if (people.size > 0) { + output.writeInt32NoTag(people.size) + for (item in people) { + item.writeToNoTag(output) + } + } + } + + class BuilderAddressBook constructor (people: Array ) { + var people : Array + + + init { + this.people = people + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + if (people.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + people[i - 1].mergeFrom(input) + } + } + } + + fun build(): AddressBook { + return AddressBook(people) + } + } + + fun mergeFrom (input: CodedInputStream) { + if (people.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + people[i - 1].mergeFrom(input) + } + } + } } + diff --git a/proto/compiler/google/protobuf/compiler/kotlin/test/com/example/tutorial/AddressBookProtos.java b/proto/compiler/google/protobuf/compiler/kotlin/test/com/example/tutorial/AddressBookProtos.java new file mode 100644 index 00000000000..02d2b3dcf3c --- /dev/null +++ b/proto/compiler/google/protobuf/compiler/kotlin/test/com/example/tutorial/AddressBookProtos.java @@ -0,0 +1,2546 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: test/addressbook.proto + +package com.example.tutorial; + +public final class AddressBookProtos { + private AddressBookProtos() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface PersonOrBuilder extends + // @@protoc_insertion_point(interface_extends:tutorial.Person) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string name = 1; + */ + java.lang.String getName(); + /** + * optional string name = 1; + */ + com.google.protobuf.ByteString + getNameBytes(); + + /** + *
+     * Unique ID number for this person.
+     * 
+ * + * optional int32 id = 2; + */ + int getId(); + + /** + * optional string email = 3; + */ + java.lang.String getEmail(); + /** + * optional string email = 3; + */ + com.google.protobuf.ByteString + getEmailBytes(); + + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + java.util.List + getPhonesList(); + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + com.example.tutorial.AddressBookProtos.Person.PhoneNumber getPhones(int index); + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + int getPhonesCount(); + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + java.util.List + getPhonesOrBuilderList(); + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder getPhonesOrBuilder( + int index); + } + /** + *
+   * [START messages]
+   * 
+ * + * Protobuf type {@code tutorial.Person} + */ + public static final class Person extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:tutorial.Person) + PersonOrBuilder { + // Use Person.newBuilder() to construct. + private Person(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private Person() { + name_ = ""; + id_ = 0; + email_ = ""; + phones_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private Person( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + name_ = s; + break; + } + case 16: { + + id_ = input.readInt32(); + break; + } + case 26: { + java.lang.String s = input.readStringRequireUtf8(); + + email_ = s; + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + phones_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000008; + } + phones_.add( + input.readMessage(com.example.tutorial.AddressBookProtos.Person.PhoneNumber.parser(), extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + phones_ = java.util.Collections.unmodifiableList(phones_); + } + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.Person.class, com.example.tutorial.AddressBookProtos.Person.Builder.class); + } + + /** + * Protobuf enum {@code tutorial.Person.PhoneType} + */ + public enum PhoneType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * MOBILE = 0; + */ + MOBILE(0), + /** + * HOME = 1; + */ + HOME(1), + /** + * WORK = 2; + */ + WORK(2), + UNRECOGNIZED(-1), + ; + + /** + * MOBILE = 0; + */ + public static final int MOBILE_VALUE = 0; + /** + * HOME = 1; + */ + public static final int HOME_VALUE = 1; + /** + * WORK = 2; + */ + public static final int WORK_VALUE = 2; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static PhoneType valueOf(int value) { + return forNumber(value); + } + + public static PhoneType forNumber(int value) { + switch (value) { + case 0: return MOBILE; + case 1: return HOME; + case 2: return WORK; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + PhoneType> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public PhoneType findValueByNumber(int number) { + return PhoneType.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.Person.getDescriptor().getEnumTypes().get(0); + } + + private static final PhoneType[] VALUES = values(); + + public static PhoneType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private PhoneType(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:tutorial.Person.PhoneType) + } + + public interface PhoneNumberOrBuilder extends + // @@protoc_insertion_point(interface_extends:tutorial.Person.PhoneNumber) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string number = 1; + */ + java.lang.String getNumber(); + /** + * optional string number = 1; + */ + com.google.protobuf.ByteString + getNumberBytes(); + + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + int getTypeValue(); + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + com.example.tutorial.AddressBookProtos.Person.PhoneType getType(); + } + /** + * Protobuf type {@code tutorial.Person.PhoneNumber} + */ + public static final class PhoneNumber extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:tutorial.Person.PhoneNumber) + PhoneNumberOrBuilder { + // Use PhoneNumber.newBuilder() to construct. + private PhoneNumber(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private PhoneNumber() { + number_ = ""; + type_ = 0; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private PhoneNumber( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + number_ = s; + break; + } + case 16: { + int rawValue = input.readEnum(); + + type_ = rawValue; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.Person.PhoneNumber.class, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder.class); + } + + public static final int NUMBER_FIELD_NUMBER = 1; + private volatile java.lang.Object number_; + /** + * optional string number = 1; + */ + public java.lang.String getNumber() { + java.lang.Object ref = number_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + number_ = s; + return s; + } + } + /** + * optional string number = 1; + */ + public com.google.protobuf.ByteString + getNumberBytes() { + java.lang.Object ref = number_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + number_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TYPE_FIELD_NUMBER = 2; + private int type_; + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public int getTypeValue() { + return type_; + } + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneType getType() { + com.example.tutorial.AddressBookProtos.Person.PhoneType result = com.example.tutorial.AddressBookProtos.Person.PhoneType.valueOf(type_); + return result == null ? com.example.tutorial.AddressBookProtos.Person.PhoneType.UNRECOGNIZED : result; + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getNumberBytes().isEmpty()) { + com.google.protobuf.GeneratedMessage.writeString(output, 1, number_); + } + if (type_ != com.example.tutorial.AddressBookProtos.Person.PhoneType.MOBILE.getNumber()) { + output.writeEnum(2, type_); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getNumberBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(1, number_); + } + if (type_ != com.example.tutorial.AddressBookProtos.Person.PhoneType.MOBILE.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, type_); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.example.tutorial.AddressBookProtos.Person.PhoneNumber)) { + return super.equals(obj); + } + com.example.tutorial.AddressBookProtos.Person.PhoneNumber other = (com.example.tutorial.AddressBookProtos.Person.PhoneNumber) obj; + + boolean result = true; + result = result && getNumber() + .equals(other.getNumber()); + result = result && type_ == other.type_; + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + hash = (37 * hash) + NUMBER_FIELD_NUMBER; + hash = (53 * hash) + getNumber().hashCode(); + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + type_; + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.example.tutorial.AddressBookProtos.Person.PhoneNumber prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code tutorial.Person.PhoneNumber} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:tutorial.Person.PhoneNumber) + com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.Person.PhoneNumber.class, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder.class); + } + + // Construct using com.example.tutorial.AddressBookProtos.Person.PhoneNumber.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + number_ = ""; + + type_ = 0; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_PhoneNumber_descriptor; + } + + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getDefaultInstanceForType() { + return com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance(); + } + + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber build() { + com.example.tutorial.AddressBookProtos.Person.PhoneNumber result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber buildPartial() { + com.example.tutorial.AddressBookProtos.Person.PhoneNumber result = new com.example.tutorial.AddressBookProtos.Person.PhoneNumber(this); + result.number_ = number_; + result.type_ = type_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.example.tutorial.AddressBookProtos.Person.PhoneNumber) { + return mergeFrom((com.example.tutorial.AddressBookProtos.Person.PhoneNumber)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.example.tutorial.AddressBookProtos.Person.PhoneNumber other) { + if (other == com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance()) return this; + if (!other.getNumber().isEmpty()) { + number_ = other.number_; + onChanged(); + } + if (other.type_ != 0) { + setTypeValue(other.getTypeValue()); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.example.tutorial.AddressBookProtos.Person.PhoneNumber parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.example.tutorial.AddressBookProtos.Person.PhoneNumber) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object number_ = ""; + /** + * optional string number = 1; + */ + public java.lang.String getNumber() { + java.lang.Object ref = number_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + number_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string number = 1; + */ + public com.google.protobuf.ByteString + getNumberBytes() { + java.lang.Object ref = number_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + number_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string number = 1; + */ + public Builder setNumber( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + number_ = value; + onChanged(); + return this; + } + /** + * optional string number = 1; + */ + public Builder clearNumber() { + + number_ = getDefaultInstance().getNumber(); + onChanged(); + return this; + } + /** + * optional string number = 1; + */ + public Builder setNumberBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + number_ = value; + onChanged(); + return this; + } + + private int type_ = 0; + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public int getTypeValue() { + return type_; + } + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public Builder setTypeValue(int value) { + type_ = value; + onChanged(); + return this; + } + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneType getType() { + com.example.tutorial.AddressBookProtos.Person.PhoneType result = com.example.tutorial.AddressBookProtos.Person.PhoneType.valueOf(type_); + return result == null ? com.example.tutorial.AddressBookProtos.Person.PhoneType.UNRECOGNIZED : result; + } + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public Builder setType(com.example.tutorial.AddressBookProtos.Person.PhoneType value) { + if (value == null) { + throw new NullPointerException(); + } + + type_ = value.getNumber(); + onChanged(); + return this; + } + /** + * optional .tutorial.Person.PhoneType type = 2; + */ + public Builder clearType() { + + type_ = 0; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:tutorial.Person.PhoneNumber) + } + + // @@protoc_insertion_point(class_scope:tutorial.Person.PhoneNumber) + private static final com.example.tutorial.AddressBookProtos.Person.PhoneNumber DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.example.tutorial.AddressBookProtos.Person.PhoneNumber(); + } + + public static com.example.tutorial.AddressBookProtos.Person.PhoneNumber getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public PhoneNumber parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PhoneNumber(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int NAME_FIELD_NUMBER = 1; + private volatile java.lang.Object name_; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ID_FIELD_NUMBER = 2; + private int id_; + /** + *
+     * Unique ID number for this person.
+     * 
+ * + * optional int32 id = 2; + */ + public int getId() { + return id_; + } + + public static final int EMAIL_FIELD_NUMBER = 3; + private volatile java.lang.Object email_; + /** + * optional string email = 3; + */ + public java.lang.String getEmail() { + java.lang.Object ref = email_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + email_ = s; + return s; + } + } + /** + * optional string email = 3; + */ + public com.google.protobuf.ByteString + getEmailBytes() { + java.lang.Object ref = email_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + email_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PHONES_FIELD_NUMBER = 4; + private java.util.List phones_; + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public java.util.List getPhonesList() { + return phones_; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public java.util.List + getPhonesOrBuilderList() { + return phones_; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public int getPhonesCount() { + return phones_.size(); + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getPhones(int index) { + return phones_.get(index); + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder getPhonesOrBuilder( + int index) { + return phones_.get(index); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getNameBytes().isEmpty()) { + com.google.protobuf.GeneratedMessage.writeString(output, 1, name_); + } + if (id_ != 0) { + output.writeInt32(2, id_); + } + if (!getEmailBytes().isEmpty()) { + com.google.protobuf.GeneratedMessage.writeString(output, 3, email_); + } + for (int i = 0; i < phones_.size(); i++) { + output.writeMessage(4, phones_.get(i)); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getNameBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(1, name_); + } + if (id_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, id_); + } + if (!getEmailBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessage.computeStringSize(3, email_); + } + for (int i = 0; i < phones_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, phones_.get(i)); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.example.tutorial.AddressBookProtos.Person)) { + return super.equals(obj); + } + com.example.tutorial.AddressBookProtos.Person other = (com.example.tutorial.AddressBookProtos.Person) obj; + + boolean result = true; + result = result && getName() + .equals(other.getName()); + result = result && (getId() + == other.getId()); + result = result && getEmail() + .equals(other.getEmail()); + result = result && getPhonesList() + .equals(other.getPhonesList()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId(); + hash = (37 * hash) + EMAIL_FIELD_NUMBER; + hash = (53 * hash) + getEmail().hashCode(); + if (getPhonesCount() > 0) { + hash = (37 * hash) + PHONES_FIELD_NUMBER; + hash = (53 * hash) + getPhonesList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.Person parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.example.tutorial.AddressBookProtos.Person prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * [START messages]
+     * 
+ * + * Protobuf type {@code tutorial.Person} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:tutorial.Person) + com.example.tutorial.AddressBookProtos.PersonOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.Person.class, com.example.tutorial.AddressBookProtos.Person.Builder.class); + } + + // Construct using com.example.tutorial.AddressBookProtos.Person.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getPhonesFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + name_ = ""; + + id_ = 0; + + email_ = ""; + + if (phonesBuilder_ == null) { + phones_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + } else { + phonesBuilder_.clear(); + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_Person_descriptor; + } + + public com.example.tutorial.AddressBookProtos.Person getDefaultInstanceForType() { + return com.example.tutorial.AddressBookProtos.Person.getDefaultInstance(); + } + + public com.example.tutorial.AddressBookProtos.Person build() { + com.example.tutorial.AddressBookProtos.Person result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.example.tutorial.AddressBookProtos.Person buildPartial() { + com.example.tutorial.AddressBookProtos.Person result = new com.example.tutorial.AddressBookProtos.Person(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.name_ = name_; + result.id_ = id_; + result.email_ = email_; + if (phonesBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008)) { + phones_ = java.util.Collections.unmodifiableList(phones_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.phones_ = phones_; + } else { + result.phones_ = phonesBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.example.tutorial.AddressBookProtos.Person) { + return mergeFrom((com.example.tutorial.AddressBookProtos.Person)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.example.tutorial.AddressBookProtos.Person other) { + if (other == com.example.tutorial.AddressBookProtos.Person.getDefaultInstance()) return this; + if (!other.getName().isEmpty()) { + name_ = other.name_; + onChanged(); + } + if (other.getId() != 0) { + setId(other.getId()); + } + if (!other.getEmail().isEmpty()) { + email_ = other.email_; + onChanged(); + } + if (phonesBuilder_ == null) { + if (!other.phones_.isEmpty()) { + if (phones_.isEmpty()) { + phones_ = other.phones_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensurePhonesIsMutable(); + phones_.addAll(other.phones_); + } + onChanged(); + } + } else { + if (!other.phones_.isEmpty()) { + if (phonesBuilder_.isEmpty()) { + phonesBuilder_.dispose(); + phonesBuilder_ = null; + phones_ = other.phones_; + bitField0_ = (bitField0_ & ~0x00000008); + phonesBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getPhonesFieldBuilder() : null; + } else { + phonesBuilder_.addAllMessages(other.phones_); + } + } + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.example.tutorial.AddressBookProtos.Person parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.example.tutorial.AddressBookProtos.Person) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string name = 1; + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder clearName() { + + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * optional string name = 1; + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + name_ = value; + onChanged(); + return this; + } + + private int id_ ; + /** + *
+       * Unique ID number for this person.
+       * 
+ * + * optional int32 id = 2; + */ + public int getId() { + return id_; + } + /** + *
+       * Unique ID number for this person.
+       * 
+ * + * optional int32 id = 2; + */ + public Builder setId(int value) { + + id_ = value; + onChanged(); + return this; + } + /** + *
+       * Unique ID number for this person.
+       * 
+ * + * optional int32 id = 2; + */ + public Builder clearId() { + + id_ = 0; + onChanged(); + return this; + } + + private java.lang.Object email_ = ""; + /** + * optional string email = 3; + */ + public java.lang.String getEmail() { + java.lang.Object ref = email_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + email_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string email = 3; + */ + public com.google.protobuf.ByteString + getEmailBytes() { + java.lang.Object ref = email_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + email_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string email = 3; + */ + public Builder setEmail( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + email_ = value; + onChanged(); + return this; + } + /** + * optional string email = 3; + */ + public Builder clearEmail() { + + email_ = getDefaultInstance().getEmail(); + onChanged(); + return this; + } + /** + * optional string email = 3; + */ + public Builder setEmailBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + email_ = value; + onChanged(); + return this; + } + + private java.util.List phones_ = + java.util.Collections.emptyList(); + private void ensurePhonesIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + phones_ = new java.util.ArrayList(phones_); + bitField0_ |= 0x00000008; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person.PhoneNumber, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder, com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder> phonesBuilder_; + + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public java.util.List getPhonesList() { + if (phonesBuilder_ == null) { + return java.util.Collections.unmodifiableList(phones_); + } else { + return phonesBuilder_.getMessageList(); + } + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public int getPhonesCount() { + if (phonesBuilder_ == null) { + return phones_.size(); + } else { + return phonesBuilder_.getCount(); + } + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber getPhones(int index) { + if (phonesBuilder_ == null) { + return phones_.get(index); + } else { + return phonesBuilder_.getMessage(index); + } + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder setPhones( + int index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber value) { + if (phonesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePhonesIsMutable(); + phones_.set(index, value); + onChanged(); + } else { + phonesBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder setPhones( + int index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder builderForValue) { + if (phonesBuilder_ == null) { + ensurePhonesIsMutable(); + phones_.set(index, builderForValue.build()); + onChanged(); + } else { + phonesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder addPhones(com.example.tutorial.AddressBookProtos.Person.PhoneNumber value) { + if (phonesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePhonesIsMutable(); + phones_.add(value); + onChanged(); + } else { + phonesBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder addPhones( + int index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber value) { + if (phonesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePhonesIsMutable(); + phones_.add(index, value); + onChanged(); + } else { + phonesBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder addPhones( + com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder builderForValue) { + if (phonesBuilder_ == null) { + ensurePhonesIsMutable(); + phones_.add(builderForValue.build()); + onChanged(); + } else { + phonesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder addPhones( + int index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder builderForValue) { + if (phonesBuilder_ == null) { + ensurePhonesIsMutable(); + phones_.add(index, builderForValue.build()); + onChanged(); + } else { + phonesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder addAllPhones( + java.lang.Iterable values) { + if (phonesBuilder_ == null) { + ensurePhonesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, phones_); + onChanged(); + } else { + phonesBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder clearPhones() { + if (phonesBuilder_ == null) { + phones_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + phonesBuilder_.clear(); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public Builder removePhones(int index) { + if (phonesBuilder_ == null) { + ensurePhonesIsMutable(); + phones_.remove(index); + onChanged(); + } else { + phonesBuilder_.remove(index); + } + return this; + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder getPhonesBuilder( + int index) { + return getPhonesFieldBuilder().getBuilder(index); + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder getPhonesOrBuilder( + int index) { + if (phonesBuilder_ == null) { + return phones_.get(index); } else { + return phonesBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public java.util.List + getPhonesOrBuilderList() { + if (phonesBuilder_ != null) { + return phonesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(phones_); + } + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder addPhonesBuilder() { + return getPhonesFieldBuilder().addBuilder( + com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance()); + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder addPhonesBuilder( + int index) { + return getPhonesFieldBuilder().addBuilder( + index, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.getDefaultInstance()); + } + /** + * repeated .tutorial.Person.PhoneNumber phones = 4; + */ + public java.util.List + getPhonesBuilderList() { + return getPhonesFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person.PhoneNumber, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder, com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder> + getPhonesFieldBuilder() { + if (phonesBuilder_ == null) { + phonesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person.PhoneNumber, com.example.tutorial.AddressBookProtos.Person.PhoneNumber.Builder, com.example.tutorial.AddressBookProtos.Person.PhoneNumberOrBuilder>( + phones_, + ((bitField0_ & 0x00000008) == 0x00000008), + getParentForChildren(), + isClean()); + phones_ = null; + } + return phonesBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:tutorial.Person) + } + + // @@protoc_insertion_point(class_scope:tutorial.Person) + private static final com.example.tutorial.AddressBookProtos.Person DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.example.tutorial.AddressBookProtos.Person(); + } + + public static com.example.tutorial.AddressBookProtos.Person getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Person parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Person(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public com.example.tutorial.AddressBookProtos.Person getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AddressBookOrBuilder extends + // @@protoc_insertion_point(interface_extends:tutorial.AddressBook) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated .tutorial.Person people = 1; + */ + java.util.List + getPeopleList(); + /** + * repeated .tutorial.Person people = 1; + */ + com.example.tutorial.AddressBookProtos.Person getPeople(int index); + /** + * repeated .tutorial.Person people = 1; + */ + int getPeopleCount(); + /** + * repeated .tutorial.Person people = 1; + */ + java.util.List + getPeopleOrBuilderList(); + /** + * repeated .tutorial.Person people = 1; + */ + com.example.tutorial.AddressBookProtos.PersonOrBuilder getPeopleOrBuilder( + int index); + } + /** + *
+   * Our address book file is just one of these.
+   * 
+ * + * Protobuf type {@code tutorial.AddressBook} + */ + public static final class AddressBook extends + com.google.protobuf.GeneratedMessage implements + // @@protoc_insertion_point(message_implements:tutorial.AddressBook) + AddressBookOrBuilder { + // Use AddressBook.newBuilder() to construct. + private AddressBook(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + } + private AddressBook() { + people_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private AddressBook( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + people_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + people_.add( + input.readMessage(com.example.tutorial.AddressBookProtos.Person.parser(), extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + people_ = java.util.Collections.unmodifiableList(people_); + } + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.AddressBook.class, com.example.tutorial.AddressBookProtos.AddressBook.Builder.class); + } + + public static final int PEOPLE_FIELD_NUMBER = 1; + private java.util.List people_; + /** + * repeated .tutorial.Person people = 1; + */ + public java.util.List getPeopleList() { + return people_; + } + /** + * repeated .tutorial.Person people = 1; + */ + public java.util.List + getPeopleOrBuilderList() { + return people_; + } + /** + * repeated .tutorial.Person people = 1; + */ + public int getPeopleCount() { + return people_.size(); + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.Person getPeople(int index) { + return people_.get(index); + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.PersonOrBuilder getPeopleOrBuilder( + int index) { + return people_.get(index); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < people_.size(); i++) { + output.writeMessage(1, people_.get(i)); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < people_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, people_.get(i)); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.example.tutorial.AddressBookProtos.AddressBook)) { + return super.equals(obj); + } + com.example.tutorial.AddressBookProtos.AddressBook other = (com.example.tutorial.AddressBookProtos.AddressBook) obj; + + boolean result = true; + result = result && getPeopleList() + .equals(other.getPeopleList()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + if (getPeopleCount() > 0) { + hash = (37 * hash) + PEOPLE_FIELD_NUMBER; + hash = (53 * hash) + getPeopleList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input); + } + public static com.example.tutorial.AddressBookProtos.AddressBook parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessage + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.example.tutorial.AddressBookProtos.AddressBook prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Our address book file is just one of these.
+     * 
+ * + * Protobuf type {@code tutorial.AddressBook} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder implements + // @@protoc_insertion_point(builder_implements:tutorial.AddressBook) + com.example.tutorial.AddressBookProtos.AddressBookOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.example.tutorial.AddressBookProtos.AddressBook.class, com.example.tutorial.AddressBookProtos.AddressBook.Builder.class); + } + + // Construct using com.example.tutorial.AddressBookProtos.AddressBook.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getPeopleFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + if (peopleBuilder_ == null) { + people_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + peopleBuilder_.clear(); + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.example.tutorial.AddressBookProtos.internal_static_tutorial_AddressBook_descriptor; + } + + public com.example.tutorial.AddressBookProtos.AddressBook getDefaultInstanceForType() { + return com.example.tutorial.AddressBookProtos.AddressBook.getDefaultInstance(); + } + + public com.example.tutorial.AddressBookProtos.AddressBook build() { + com.example.tutorial.AddressBookProtos.AddressBook result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.example.tutorial.AddressBookProtos.AddressBook buildPartial() { + com.example.tutorial.AddressBookProtos.AddressBook result = new com.example.tutorial.AddressBookProtos.AddressBook(this); + int from_bitField0_ = bitField0_; + if (peopleBuilder_ == null) { + if (((bitField0_ & 0x00000001) == 0x00000001)) { + people_ = java.util.Collections.unmodifiableList(people_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.people_ = people_; + } else { + result.people_ = peopleBuilder_.build(); + } + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.example.tutorial.AddressBookProtos.AddressBook) { + return mergeFrom((com.example.tutorial.AddressBookProtos.AddressBook)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.example.tutorial.AddressBookProtos.AddressBook other) { + if (other == com.example.tutorial.AddressBookProtos.AddressBook.getDefaultInstance()) return this; + if (peopleBuilder_ == null) { + if (!other.people_.isEmpty()) { + if (people_.isEmpty()) { + people_ = other.people_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensurePeopleIsMutable(); + people_.addAll(other.people_); + } + onChanged(); + } + } else { + if (!other.people_.isEmpty()) { + if (peopleBuilder_.isEmpty()) { + peopleBuilder_.dispose(); + peopleBuilder_ = null; + people_ = other.people_; + bitField0_ = (bitField0_ & ~0x00000001); + peopleBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getPeopleFieldBuilder() : null; + } else { + peopleBuilder_.addAllMessages(other.people_); + } + } + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.example.tutorial.AddressBookProtos.AddressBook parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.example.tutorial.AddressBookProtos.AddressBook) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List people_ = + java.util.Collections.emptyList(); + private void ensurePeopleIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + people_ = new java.util.ArrayList(people_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person, com.example.tutorial.AddressBookProtos.Person.Builder, com.example.tutorial.AddressBookProtos.PersonOrBuilder> peopleBuilder_; + + /** + * repeated .tutorial.Person people = 1; + */ + public java.util.List getPeopleList() { + if (peopleBuilder_ == null) { + return java.util.Collections.unmodifiableList(people_); + } else { + return peopleBuilder_.getMessageList(); + } + } + /** + * repeated .tutorial.Person people = 1; + */ + public int getPeopleCount() { + if (peopleBuilder_ == null) { + return people_.size(); + } else { + return peopleBuilder_.getCount(); + } + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.Person getPeople(int index) { + if (peopleBuilder_ == null) { + return people_.get(index); + } else { + return peopleBuilder_.getMessage(index); + } + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder setPeople( + int index, com.example.tutorial.AddressBookProtos.Person value) { + if (peopleBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePeopleIsMutable(); + people_.set(index, value); + onChanged(); + } else { + peopleBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder setPeople( + int index, com.example.tutorial.AddressBookProtos.Person.Builder builderForValue) { + if (peopleBuilder_ == null) { + ensurePeopleIsMutable(); + people_.set(index, builderForValue.build()); + onChanged(); + } else { + peopleBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder addPeople(com.example.tutorial.AddressBookProtos.Person value) { + if (peopleBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePeopleIsMutable(); + people_.add(value); + onChanged(); + } else { + peopleBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder addPeople( + int index, com.example.tutorial.AddressBookProtos.Person value) { + if (peopleBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePeopleIsMutable(); + people_.add(index, value); + onChanged(); + } else { + peopleBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder addPeople( + com.example.tutorial.AddressBookProtos.Person.Builder builderForValue) { + if (peopleBuilder_ == null) { + ensurePeopleIsMutable(); + people_.add(builderForValue.build()); + onChanged(); + } else { + peopleBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder addPeople( + int index, com.example.tutorial.AddressBookProtos.Person.Builder builderForValue) { + if (peopleBuilder_ == null) { + ensurePeopleIsMutable(); + people_.add(index, builderForValue.build()); + onChanged(); + } else { + peopleBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder addAllPeople( + java.lang.Iterable values) { + if (peopleBuilder_ == null) { + ensurePeopleIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, people_); + onChanged(); + } else { + peopleBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder clearPeople() { + if (peopleBuilder_ == null) { + people_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + peopleBuilder_.clear(); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public Builder removePeople(int index) { + if (peopleBuilder_ == null) { + ensurePeopleIsMutable(); + people_.remove(index); + onChanged(); + } else { + peopleBuilder_.remove(index); + } + return this; + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.Person.Builder getPeopleBuilder( + int index) { + return getPeopleFieldBuilder().getBuilder(index); + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.PersonOrBuilder getPeopleOrBuilder( + int index) { + if (peopleBuilder_ == null) { + return people_.get(index); } else { + return peopleBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .tutorial.Person people = 1; + */ + public java.util.List + getPeopleOrBuilderList() { + if (peopleBuilder_ != null) { + return peopleBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(people_); + } + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.Person.Builder addPeopleBuilder() { + return getPeopleFieldBuilder().addBuilder( + com.example.tutorial.AddressBookProtos.Person.getDefaultInstance()); + } + /** + * repeated .tutorial.Person people = 1; + */ + public com.example.tutorial.AddressBookProtos.Person.Builder addPeopleBuilder( + int index) { + return getPeopleFieldBuilder().addBuilder( + index, com.example.tutorial.AddressBookProtos.Person.getDefaultInstance()); + } + /** + * repeated .tutorial.Person people = 1; + */ + public java.util.List + getPeopleBuilderList() { + return getPeopleFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person, com.example.tutorial.AddressBookProtos.Person.Builder, com.example.tutorial.AddressBookProtos.PersonOrBuilder> + getPeopleFieldBuilder() { + if (peopleBuilder_ == null) { + peopleBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + com.example.tutorial.AddressBookProtos.Person, com.example.tutorial.AddressBookProtos.Person.Builder, com.example.tutorial.AddressBookProtos.PersonOrBuilder>( + people_, + ((bitField0_ & 0x00000001) == 0x00000001), + getParentForChildren(), + isClean()); + people_ = null; + } + return peopleBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:tutorial.AddressBook) + } + + // @@protoc_insertion_point(class_scope:tutorial.AddressBook) + private static final com.example.tutorial.AddressBookProtos.AddressBook DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.example.tutorial.AddressBookProtos.AddressBook(); + } + + public static com.example.tutorial.AddressBookProtos.AddressBook getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public AddressBook parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AddressBook(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public com.example.tutorial.AddressBookProtos.AddressBook getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_tutorial_Person_descriptor; + private static final + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_tutorial_Person_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_tutorial_Person_PhoneNumber_descriptor; + private static final + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_tutorial_AddressBook_descriptor; + private static final + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_tutorial_AddressBook_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\026test/addressbook.proto\022\010tutorial\"\325\001\n\006P" + + "erson\022\014\n\004name\030\001 \001(\t\022\n\n\002id\030\002 \001(\005\022\r\n\005email" + + "\030\003 \001(\t\022,\n\006phones\030\004 \003(\0132\034.tutorial.Person" + + ".PhoneNumber\032G\n\013PhoneNumber\022\016\n\006number\030\001 " + + "\001(\t\022(\n\004type\030\002 \001(\0162\032.tutorial.Person.Phon" + + "eType\"+\n\tPhoneType\022\n\n\006MOBILE\020\000\022\010\n\004HOME\020\001" + + "\022\010\n\004WORK\020\002\"/\n\013AddressBook\022 \n\006people\030\001 \003(" + + "\0132\020.tutorial.PersonBP\n\024com.example.tutor" + + "ialB\021AddressBookProtos\252\002$Google.Protobuf" + + ".Examples.AddressBookb\006proto3" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_tutorial_Person_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_tutorial_Person_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_tutorial_Person_descriptor, + new java.lang.String[] { "Name", "Id", "Email", "Phones", }); + internal_static_tutorial_Person_PhoneNumber_descriptor = + internal_static_tutorial_Person_descriptor.getNestedTypes().get(0); + internal_static_tutorial_Person_PhoneNumber_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_tutorial_Person_PhoneNumber_descriptor, + new java.lang.String[] { "Number", "Type", }); + internal_static_tutorial_AddressBook_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_tutorial_AddressBook_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_tutorial_AddressBook_descriptor, + new java.lang.String[] { "People", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/proto/compiler/google/protobuf/compiler/kotlin/test/test/addressbook.proto b/proto/compiler/google/protobuf/compiler/kotlin/test/test/addressbook.proto new file mode 100644 index 00000000000..f97aeb68a69 --- /dev/null +++ b/proto/compiler/google/protobuf/compiler/kotlin/test/test/addressbook.proto @@ -0,0 +1,18 @@ +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 +} +class AddressBook { + val people : List +} diff --git a/proto/compiler/src/AddressBook.kt b/proto/compiler/src/AddressBook.kt new file mode 100644 index 00000000000..58ebeb27c62 --- /dev/null +++ b/proto/compiler/src/AddressBook.kt @@ -0,0 +1,62 @@ +/** + * Created by user on 7/13/16. + */ +class AddressBook private constructor (people: Array ) { + var people : Array + private set + + init { + this.people = people + } + + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + if (people.size > 0) { + output.writeInt32NoTag(people.size) + for (item in people) { + item.writeToNoTag(output) + } + } + } + + class BuilderAddressBook constructor (people: Array ) { + var people : Array + + init { + this.people = people + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + if (people.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + people[i - 1].mergeFrom(input) + } + } + } + + fun build(): AddressBook { + return AddressBook(people) + } + } + + fun mergeFrom (input: CodedInputStream) { + if (people.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + people[i - 1].mergeFrom(input) + } + } + } +} + + diff --git a/proto/compiler/src/CodedInputStream.kt b/proto/compiler/src/CodedInputStream.kt index 827bcfb3282..1168cd65d94 100644 --- a/proto/compiler/src/CodedInputStream.kt +++ b/proto/compiler/src/CodedInputStream.kt @@ -24,14 +24,22 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) - return readRawVarint32() + return readInt32NoTag() } // Note that unsigned integer types are stored as their signed counterparts with top bit // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all // methods reading unsigned ints simply redirect call to corresponding signed-reading method fun readUInt32(expectedFieldNumber: Int): Int { - return readInt32(expectedFieldNumber) + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readUInt32NoTag() + } + + fun readUInt32NoTag(): Int { + return readInt32NoTag() } fun readInt64(expectedFieldNumber: Int): Long { @@ -39,12 +47,20 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, actualWireType, WireType.VARINT) - return readRawVarint64() + return readInt64NoTag() } // See note on unsigned integers implementations above fun readUInt64(expectedFieldNumber: Int): Long { - return readUInt64(expectedFieldNumber) + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, actualWireType, WireType.VARINT) + return readUInt64NoTag() + } + + fun readUInt64NoTag(): Long { + return readInt64NoTag() } fun readBool(expectedFieldNumber: Int): Boolean { @@ -52,7 +68,11 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, actualWireType, WireType.VARINT) - val readValue = readRawVarint32() + return readBoolNoTag() + } + + fun readBoolNoTag(): Boolean { + val readValue = readInt32NoTag() val boolValue = when (readValue) { 0 -> false 1 -> true @@ -63,7 +83,15 @@ class CodedInputStream(input: java.io.InputStream) { // Reading enums is like reading one int32 number. Caller is responsible for converting this ordinal to enum-object fun readEnum(expectedFieldNumber: Int): Int { - return readInt32(expectedFieldNumber) + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) + return readEnumNoTag() + } + + fun readEnumNoTag(): Int { + return readUInt32NoTag() } fun readSInt32(expectedFieldNumber: Int): Int { @@ -71,7 +99,11 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) - return readZigZag32() + return readSInt32NoTag() + } + + fun readSInt32NoTag(): Int { + return readZigZag32NoTag() } fun readSInt64(expectedFieldNumber: Int): Long { @@ -79,7 +111,7 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType) - return readZigZag64() + return readZigZag64NoTag() } fun readFixed32(expectedFieldNumber: Int): Int { @@ -87,11 +119,23 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_32, actualWireType) + return readFixed32NoInt() + } + + fun readFixed32NoInt(): Int { return readLittleEndianInt() } fun readSFixed32(expectedFieldNumber: Int): Int { - return readFixed32(expectedFieldNumber) + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_32, actualWireType) + return readSFixed32NoTag() + } + + fun readSFixed32NoTag(): Int { + return readLittleEndianInt() } fun readFixed64(expectedFieldNumber: Int): Long { @@ -99,11 +143,23 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_64, actualWireType) + return readFixed64NoTag() + } + + fun readFixed64NoTag(): Long { return readLittleEndianLong() } fun readSFixed64(expectedFieldNumber: Int): Long { - return readFixed64(expectedFieldNumber) + val tag = readTag() + val actualFieldNumber = WireFormat.getTagFieldNumber(tag) + val actualWireType = WireFormat.getTagWireType(tag) + checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_64, actualWireType) + return readSFixed64NoTag() + } + + fun readSFixed64NoTag(): Long { + return readLittleEndianLong() } fun readDouble(expectedFieldNumber: Int): Double { @@ -111,6 +167,10 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_64, actualWireType) + return readDoubleNoTag() + } + + fun readDoubleNoTag(): Double { return readLittleEndianDouble() } @@ -119,6 +179,10 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.FIX_32, actualWireType) + return readFloatNoTag() + } + + fun readFloatNoTag(): Float { return readLittleEndianFloat() } @@ -127,11 +191,14 @@ class CodedInputStream(input: java.io.InputStream) { val actualFieldNumber = WireFormat.getTagFieldNumber(tag) val actualWireType = WireFormat.getTagWireType(tag) checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.LENGTH_DELIMITED, actualWireType) - val length = readRawVarint32() + return readStringNoTag() + } + + fun readStringNoTag(): String { + val length = readInt32NoTag() val value = String(readRawBytes(length)) return value } - /** ============ Utility methods ================== * They are left non-private for cases when one wants to implement her/his own protocol format. * Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags. @@ -191,7 +258,7 @@ class CodedInputStream(input: java.io.InputStream) { if (isAtEnd()) { return 0 // we can safely return 0 as sign of end of message, because 0-tags are illegal } - val tag = readRawVarint32() + val tag = readInt32NoTag() if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted throw InvalidProtocolBufferException("Invalid tag 0") } @@ -199,7 +266,7 @@ class CodedInputStream(input: java.io.InputStream) { } // reads varint not larger than 32-bit integer according to protobuf varint-encoding - fun readRawVarint32(): Int { + fun readInt32NoTag(): Int { var done: Boolean = false var result: Int = 0 var step: Int = 0 @@ -207,10 +274,10 @@ class CodedInputStream(input: java.io.InputStream) { val byte: Int = bufferedInput.read() result = result or ( - (byte and VARINT_INFO_BITS_MASK) - shl - (VARINT_INFO_BITS_COUNT * step) - ) + (byte and VARINT_INFO_BITS_MASK) + shl + (VARINT_INFO_BITS_COUNT * step) + ) step++ if ((byte and VARINT_UTIL_BIT_MASK) == 0) { done = true @@ -220,7 +287,7 @@ class CodedInputStream(input: java.io.InputStream) { } // reads varint not larger than 64-bit integer according to protobuf varint-encoding - fun readRawVarint64(): Long { + fun readInt64NoTag(): Long { var done: Boolean = false var result: Long = 0 var step: Int = 0 @@ -228,10 +295,10 @@ class CodedInputStream(input: java.io.InputStream) { val byte: Int = bufferedInput.read() result = result or ( - (byte and VARINT_INFO_BITS_MASK).toLong() - shl - (VARINT_INFO_BITS_COUNT * step) - ) + (byte and VARINT_INFO_BITS_MASK).toLong() + shl + (VARINT_INFO_BITS_COUNT * step) + ) step++ if ((byte and VARINT_UTIL_BIT_MASK) == 0 || byte == -1) { done = true @@ -241,14 +308,14 @@ class CodedInputStream(input: java.io.InputStream) { } // reads zig-zag encoded integer not larger than 32-bit long - fun readZigZag32(): Int { - val value = readRawVarint32() + fun readZigZag32NoTag(): Int { + val value = readInt32NoTag() return (value shr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number } // reads zig-zag encoded integer not larger than 64-bit long - fun readZigZag64(): Long { - val value = readRawVarint64() + fun readZigZag64NoTag(): Long { + val value = readInt64NoTag() return (value shr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number } diff --git a/proto/compiler/src/CodedOutputStream.kt b/proto/compiler/src/CodedOutputStream.kt index 97cf7c31f96..d5e132bc344 100644 --- a/proto/compiler/src/CodedOutputStream.kt +++ b/proto/compiler/src/CodedOutputStream.kt @@ -8,114 +8,184 @@ import java.nio.ByteOrder class CodedOutputStream(val output: java.io.OutputStream) { fun writeTag(fieldNumber: Int, type: WireType) { val tag = (fieldNumber shl 3) or type.ordinal - writeVarint32(tag) + writeInt32NoTag(tag) } - fun writeInt32(fieldNumber: Int, value: Int) { + fun writeInt32(fieldNumber: Int, value: Int?) { + value ?: return writeTag(fieldNumber, WireType.VARINT) - writeVarint32(value) + writeInt32NoTag(value) } // Note that unsigned integer types are stored as their signed counterparts with top bit // simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all // methods, writing unsigned ints simply redirect call to corresponding signed-writing method - fun writeUInt32(fieldNumber: Int, value: Int) { + fun writeUInt32(fieldNumber: Int, value: Int?) { + value ?: return writeInt32(fieldNumber, value) } - fun writeInt64(fieldNumber: Int, value: Long) { + fun writeInt64(fieldNumber: Int, value: Long?) { + value ?: return writeTag(fieldNumber, WireType.VARINT) - writeVarint64(value) + writeInt64NoTag(value) } // See notes on unsigned integers implementation above - fun writeUIn64(fieldNumber: Int, value: Long) { + fun writeUInt64(fieldNumber: Int, value: Long?) { + value ?: return writeInt64(fieldNumber, value) } - fun writeBool(fieldNumber: Int, value: Boolean) { - writeInt32(fieldNumber, if (value) 1 else 0) + fun writeBool(fieldNumber: Int, value: Boolean?) { + value ?: return + writeTag(fieldNumber, WireType.VARINT) + writeBoolNoTag(value) + } + + fun writeBoolNoTag(value: Boolean) { + writeInt32NoTag(if (value) 1 else 0) } // Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal - fun writeEnum(fieldNumber: Int, value: Int) { - writeInt32(fieldNumber, value) + fun writeEnum(fieldNumber: Int, value: Int?) { + value ?: return + writeTag(fieldNumber, WireType.VARINT) + writeEnumNoTag(value) } - fun writeSInt32(fieldNumber: Int, value: Int) { - writeInt32(fieldNumber, (value shl 1) xor (value shr 31)) + fun writeEnumNoTag(value: Int) { + writeInt32NoTag(value) } - fun writeSInt64(fieldNumber: Int, value: Long) { - writeInt64(fieldNumber, (value shl 1) xor (value shr 31)) + fun writeSInt32(fieldNumber: Int, value: Int?) { + value ?: return + writeTag(fieldNumber, WireType.VARINT) + writeSInt32NoTag(value) } - fun writeFixed32(fieldNumber: Int, value: Int) { + fun writeSInt32NoTag(value: Int) { + writeInt32NoTag((value shl 1) xor (value shr 31)) + } + + fun writeSInt64(fieldNumber: Int, value: Long?) { + value ?: return + writeTag(fieldNumber, WireType.VARINT) + writeSInt64NoTag(value) + } + + fun writeSInt64NoTag(value: Long) { + writeInt64NoTag((value shl 1) xor (value shr 31)) + } + + fun writeFixed32(fieldNumber: Int, value: Int?) { + value ?: return writeTag(fieldNumber, WireType.FIX_32) + writeFixed32NoTag(value) + } + + fun writeFixed32NoTag(value: Int) { writeLittleEndian(value) } // See notes on unsigned integers implementation above - fun writeSFixed32(fieldNumber: Int, value: Int) { - writeFixed32(fieldNumber, value) + fun writeSFixed32(fieldNumber: Int, value: Int?) { + value ?: return + writeTag(fieldNumber, WireType.FIX_32) + writeSFixed32NoTag(value) } - fun writeFixed64(fieldNumber: Int, value: Long) { + fun writeSFixed32NoTag(value: Int) { + writeLittleEndian(value) + } + + fun writeFixed64(fieldNumber: Int, value: Long?) { + value ?: return writeTag(fieldNumber, WireType.FIX_64) + writeFixed64NoTag(value) + } + + fun writeFixed64NoTag(value: Long) { writeLittleEndian(value) } // See notes on unsigned integers implementation above - fun writeSFixed64(fieldNumber: Int, value: Long) { - writeFixed64(fieldNumber, value) - } - - fun writeDouble(fieldNumber: Int, value: Double) { + fun writeSFixed64(fieldNumber: Int, value: Long?) { + value ?: return writeTag(fieldNumber, WireType.FIX_64) + writeSFixed64NoTag(value) + } + + fun writeSFixed64NoTag(value: Long) { writeLittleEndian(value) } - fun writeFloat(fieldNumber: Int, value: Float) { + fun writeDouble(fieldNumber: Int, value: Double?) { + value ?: return + writeTag(fieldNumber, WireType.FIX_64) + writeDoubleNoTag(value) + } + + fun writeDoubleNoTag(value: Double) { + writeLittleEndian(value) + } + + fun writeFloat(fieldNumber: Int, value: Float?) { + value ?: return writeTag(fieldNumber, WireType.FIX_32) + writeFloatNoTag(value) + } + + fun writeFloatNoTag(value: Float) { writeLittleEndian(value) } - fun writeString(fieldNumber: Int, value: String) { + fun writeString(fieldNumber: Int, value: String?) { + value ?: return writeTag(fieldNumber, WireType.LENGTH_DELIMITED) - writeVarint32(value.length) + writeStringNoTag(value) + } + + fun writeStringNoTag(value: String) { + writeInt32NoTag(value.length) output.write(value.toByteArray()) } - fun writeLittleEndian(value: Int) { + fun writeLittleEndian(value: Int?) { + value ?: return val bb = ByteBuffer.allocate(4) bb.order(ByteOrder.LITTLE_ENDIAN) bb.putInt(value) output.write(bb.array()) } - fun writeLittleEndian(value: Long) { + fun writeLittleEndian(value: Long?) { + value ?: return val bb = ByteBuffer.allocate(8) bb.order(ByteOrder.LITTLE_ENDIAN) bb.putLong(value) output.write(bb.array()) } - fun writeLittleEndian(value: Double) { + fun writeLittleEndian(value: Double?) { + value ?: return val bb = ByteBuffer.allocate(8) bb.order(ByteOrder.LITTLE_ENDIAN) bb.putDouble(value) output.write(bb.array()) } - fun writeLittleEndian(value: Float) { + fun writeLittleEndian(value: Float?) { + value ?: return val bb = ByteBuffer.allocate(4) bb.order(ByteOrder.LITTLE_ENDIAN) bb.putFloat(value) output.write(bb.array()) } - fun writeVarint32(value: Int) { - var curValue = value + fun writeInt32NoTag(value: Int?) { + value ?: return + var curValue: Int = value // we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding val res = ByteArray(5) @@ -139,8 +209,9 @@ class CodedOutputStream(val output: java.io.OutputStream) { output.write(res, 0, resSize) } - fun writeVarint64(value: Long) { - var curValue = value + fun writeInt64NoTag(value: Long?) { + value ?: return + var curValue: Long = value // we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding val res = ByteArray(10) diff --git a/proto/compiler/src/Message.kt b/proto/compiler/src/Message.kt index 0cb812de2db..3b6f26c6630 100644 --- a/proto/compiler/src/Message.kt +++ b/proto/compiler/src/Message.kt @@ -4,7 +4,6 @@ interface Message { fun writeTo(output: CodedOutputStream) - fun readFrom(input: CodedInputStream) : Message fun getBuilder() : Builder //TODO: think about something similar to static method getDefaultInstance() diff --git a/proto/compiler/src/Person.kt b/proto/compiler/src/Person.kt new file mode 100644 index 00000000000..02b683ac651 --- /dev/null +++ b/proto/compiler/src/Person.kt @@ -0,0 +1,158 @@ +class Person constructor (name: kotlin.String?, id: Int?, email: kotlin.String?, phones: Array ) { + var name : kotlin.String? + private set + + var id : Int? + private set + + var email : kotlin.String? + private set + + var phones : Array + private set + + + init { + this.name = name + this.id = id + this.email = email + this.phones = phones + } + 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 constructor (number: kotlin.String?, type: PhoneType?) { + var number : kotlin.String? + private set + + var type : PhoneType? + private set + + + init { + this.number = number + this.type = type + } + + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + output.writeString (1, number) + output.writeEnum (2, type?.ord) + } + + class BuilderPhoneNumber constructor (number: kotlin.String?, type: PhoneType?) { + var number : kotlin.String? + + var type : PhoneType? + + + init { + this.number = number + this.type = type + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + number = input.readString(1) + type = PhoneType.fromIntToPhoneType(input.readEnum(2)) + } + + fun build(): PhoneNumber { + return PhoneNumber(number, type) + } + } + + fun mergeFrom (input: CodedInputStream) { + number = input.readString(1) + type = PhoneType.fromIntToPhoneType(input.readEnum(2)) + } + } + + + fun writeTo (output: CodedOutputStream) { + writeToNoTag(output) + } + + fun writeToNoTag (output: CodedOutputStream) { + output.writeString (1, name) + output.writeInt32 (2, id) + output.writeString (3, email) + if (phones.size > 0) { + output.writeInt32NoTag(phones.size) + for (item in phones) { + item.writeToNoTag(output) + } + } + } + + class BuilderPerson constructor (name: kotlin.String?, id: Int?, email: kotlin.String?, phones: Array ) { + var name : kotlin.String? + + var id : Int? + + var email : kotlin.String? + + var phones : Array + + + init { + this.name = name + this.id = id + this.email = email + this.phones = phones + } + + fun readFrom (input: CodedInputStream) { + readFromNoTag(input) + } + + fun readFromNoTag (input: CodedInputStream) { + name = input.readString(1) + id = input.readInt32(2) + email = input.readString(3) + if (phones.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + phones[i - 1].mergeFrom(input) + } + } + } + + fun build(): Person { + return Person(name, id, email, phones) + } + } + + fun mergeFrom (input: CodedInputStream) { + name = input.readString(1) + id = input.readInt32(2) + email = input.readString(3) + if (phones.size > 0) { + val tag = input.readTag() + val listSize = input.readInt32NoTag() + for (i in 1..listSize) { + phones[i - 1].mergeFrom(input) + } + } + } +} diff --git a/proto/compiler/src/TestMessages.kt b/proto/compiler/src/TestMessages.kt index d148ece15a1..9392e5b9939 100644 --- a/proto/compiler/src/TestMessages.kt +++ b/proto/compiler/src/TestMessages.kt @@ -8,12 +8,20 @@ import java.io.ByteArrayOutputStream fun testMessageSerialization() { val s = ByteArrayOutputStream() val outs = CodedOutputStream(s) - val msg = PersonMessage(name = "John Doe", id = 42, hasCat = true) + val msg = Person( + name = "John Doe", + id = 42, + email = "wtf@dsada.com", + phones = arrayOf ( + Person.PhoneNumber("8-800-555-35-35", Person.PhoneType.WORK), + Person.PhoneNumber("228-322", Person.PhoneType.HOME) + ) + ) msg.writeTo(outs) val ins = CodedInputStream(ByteArrayInputStream(s.toByteArray())) - val readMsg = PersonMessage("", 0, false) - readMsg.readFrom(ins) + val readMsg = Person("", 0, "", arrayOf()) + readMsg.mergeFrom(ins) assert(msg == readMsg) }