diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc b/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc index b2377c83172..62ab8a41164 100755 Binary files a/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc and b/proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc differ diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc index d3e9824a5b7..d857361e478 100644 --- a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc +++ b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_class_generator.cc @@ -290,22 +290,26 @@ void ClassGenerator::generateParseMethods(io::Printer *printer) const { for (int i = 0; i < properties.size(); ++i) { vars["fieldNumber"] = std::to_string(properties[i]->getFieldNumber()); vars["kotlinFunSuffix"] = properties[i]->getKotlinFunctionSuffix(); + vars["kotlinWireType"] = properties[i]->getWireType(); + vars["dl"] = "$"; printer->Print(vars, "$fieldNumber$ -> "); - // code for serialization arrays and messages consists of more than one line and needs enclosing brackets - if (properties[i]->getProtoLabel() == FieldDescriptor::LABEL_REPEATED - || properties[i]->getProtoType() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print("{\n"); - printer->Indent(); - } + printer->Print("{\n"); + printer->Indent(); + + // check that wire type of that field is equal to expected + printer->Print(vars, "if (wireType != $kotlinWireType$) {\n"); + printer->Indent(); + printer->Print(vars, "throw InvalidProtocolBufferException(\"" + "Error: Field number $fieldNumber$ has wire type $kotlinWireType$" + " but read $dl${wireType.toString()}\")"); + printer->Outdent(); + printer->Print("}\n"); properties[i]->generateSerializationCode(printer, /* isRead = */ true, /* noTag = */ true); - if (properties[i]->getProtoLabel() == FieldDescriptor::LABEL_REPEATED - || properties[i]->getProtoType() == FieldDescriptor::TYPE_MESSAGE) { - printer->Outdent(); - printer->Print("}\n"); - } + printer->Outdent(); + printer->Print("}\n"); } // TODO: add parsing of unknown fields diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc index b3f435213da..3a602ef7c1e 100644 --- a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc +++ b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.cc @@ -582,6 +582,13 @@ FieldGenerator FieldGenerator::getUnderlyingTypeGenerator() const { return *this; } +string FieldGenerator::getWireType() const { + if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) { + return "WireType.LENGTH_DELIMITED"; + } + return name_resolving::protobufTypeToKotlinWireType(descriptor->type()); +} + } // namespace kotlin } // namespace compiler diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h index 6c483789d45..c635145612c 100644 --- a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h +++ b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_field_generator.h @@ -81,6 +81,8 @@ public: /* Return function name in enum namespace that converts from enum to Int */ string getEnumFromIntConverter() const; + + string getWireType() const; void generateCode(io::Printer * printer, bool isBuilder) const; void generateSerializationCode(io::Printer * printer, bool isRead = false, bool noTag = false) const; void generateSizeEstimationCode(io::Printer * printer, string varName, bool noTag = false) const; diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.cc b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.cc index 3b29043a6b5..a4590b8f2d4 100644 --- a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.cc +++ b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.cc @@ -156,6 +156,44 @@ string protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type) { } } +string protobufTypeToKotlinWireType(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_DOUBLE: + return "WireType.FIX_64"; + case FieldDescriptor::TYPE_FLOAT: + return "WireType.FIX_32"; + case FieldDescriptor::TYPE_INT64: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_UINT64: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_INT32: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_FIXED64: + return "WireType.FIX_64"; + case FieldDescriptor::TYPE_FIXED32: + return "WireType.FIX_32"; + case FieldDescriptor::TYPE_BOOL: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_STRING: + return "WireType.LENGTH_DELIMITED"; + case FieldDescriptor::TYPE_MESSAGE: + return "WireType.LENGTH_DELIMITED"; + case FieldDescriptor::TYPE_BYTES: + return "WireType.LENGTH_DELIMITED"; + case FieldDescriptor::TYPE_UINT32: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_ENUM: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_SFIXED32: + return "WireType.FIX_32"; + case FieldDescriptor::TYPE_SFIXED64: + return "WireType.FIX_64"; + case FieldDescriptor::TYPE_SINT32: + return "WireType.VARINT"; + case FieldDescriptor::TYPE_SINT64: + return "WireType.VARINT"; + } +} } // namespace name_resolving NameResolver::NameResolver() { diff --git a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.h b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.h index 93910c9b586..fac4149615b 100644 --- a/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.h +++ b/proto/compiler/google/src/google/protobuf/compiler/kotlin/src/kotlin_name_resolver.h @@ -41,6 +41,8 @@ std::string protobufTypeToInitValue(FieldDescriptor::Type type); std::string protobufToKotlinType(FieldDescriptor::Type type); +std::string protobufTypeToKotlinWireType(FieldDescriptor::Type type); + /** * 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