From d958125c4b75f2a51cc817f1a4aa282c0264e879 Mon Sep 17 00:00:00 2001 From: dsavvinov Date: Fri, 15 Jul 2016 16:47:26 +0300 Subject: [PATCH] Compiler: convertors from protobuf types to various Kotlin entities refactored in separate namespace --- .../kotlin/src/kotlin_field_generator.cc | 169 +----------------- .../kotlin/src/kotlin_field_generator.h | 12 -- .../kotlin/src/kotlin_name_resolver.cc | 148 +++++++++++++++ .../kotlin/src/kotlin_name_resolver.h | 17 ++ 4 files changed, 172 insertions(+), 174 deletions(-) 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 be6ee75f6e2..4744b1a4bd0 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 @@ -14,122 +14,6 @@ namespace protobuf { namespace compiler { namespace kotlin { -/** - * Gets equivalent Kotlin-type for a given field descriptor. - * This method takes protobuf field type into account, adding 'List<>' - * for repeated fields, and '?' for optional. - */ -string FieldGenerator::protobufToKotlinField() const { - string preamble = "", - postamble = ""; - switch (modifier) { - case FieldDescriptor::LABEL_REQUIRED: - break; - case FieldDescriptor::LABEL_OPTIONAL: - postamble = "?"; - break; - case FieldDescriptor::LABEL_REPEATED: - #ifndef KOTLIN_GENERATED_CODE_LANGUAGE_LEVEL_LOW - preamble = "MutableList <"; - postamble = "> "; - break; - #else - preamble = "Array <"; - postamble = "> "; - break; - #endif - } - return preamble + protobufToKotlinType() + postamble; -} - -/** - * Simply maps protobuf field type to corresponding Kotlin. - */ -// TODO: refactor in separate static namespace -string FieldGenerator::protobufToKotlinType() const { - FieldDescriptor::Type type = descriptor->type(); - switch(type) { - case FieldDescriptor::TYPE_BOOL: - return "Boolean"; - case FieldDescriptor::TYPE_BYTES: - return "ByteArray"; - case FieldDescriptor::TYPE_DOUBLE: - return "Double"; - case FieldDescriptor::TYPE_ENUM: - return string(descriptor->enum_type()->name()); - case FieldDescriptor::TYPE_FIXED32: - // we map uint32 into Int, storing top bit in sign bit - return "Int"; - case FieldDescriptor::TYPE_FIXED64: - // we map uint64 into Long, storing top bit in sign bit - return "Long"; - case FieldDescriptor::TYPE_FLOAT: - return "Float"; - case FieldDescriptor::TYPE_INT32: - return "Int"; - case FieldDescriptor::TYPE_INT64: - return "Long"; - case FieldDescriptor::TYPE_MESSAGE: - return string(descriptor->message_type()->name()); - case FieldDescriptor::TYPE_SFIXED32: - return "Int"; - case FieldDescriptor::TYPE_SFIXED64: - return "Long"; - case FieldDescriptor::TYPE_SINT32: - return "Int"; - case FieldDescriptor::TYPE_SINT64: - return "Long"; - case FieldDescriptor::TYPE_STRING: - return "kotlin.String"; - case FieldDescriptor::TYPE_UINT32: - return "Int"; // see notes for TYPE_FIXED32 - case FieldDescriptor::TYPE_UINT64: - return "Long"; // see notes for TYPE_FIXED64 - } -} - -// TODO: refactor in separate static -string FieldGenerator::protobufTypeToInitValue(FieldDescriptor const * descriptor) const { - FieldDescriptor::Type type = descriptor->type(); - switch(type) { - case FieldDescriptor::TYPE_BOOL: - return "false"; - case FieldDescriptor::TYPE_BYTES: - return "ByteArray(0)"; - case FieldDescriptor::TYPE_DOUBLE: - return "0.0"; - case FieldDescriptor::TYPE_ENUM: { - string enumType = descriptor->enum_type()->name(); - return enumType + ".fromIntTo" + enumType + "(0)"; // produce enum from 0, as demanded by Google - } - case FieldDescriptor::TYPE_FIXED32: - return "0"; - case FieldDescriptor::TYPE_FIXED64: - return "0L"; - case FieldDescriptor::TYPE_FLOAT: - return "0f"; - case FieldDescriptor::TYPE_INT32: - return "0"; - case FieldDescriptor::TYPE_INT64: - return "0L"; - case FieldDescriptor::TYPE_MESSAGE: - return string(descriptor->message_type()->name()) + "()"; - case FieldDescriptor::TYPE_SFIXED32: - return "0"; - case FieldDescriptor::TYPE_SFIXED64: - return "0L"; - case FieldDescriptor::TYPE_SINT32: - return "0"; - case FieldDescriptor::TYPE_SINT64: - return "0L"; - case FieldDescriptor::TYPE_STRING: - return "\"\""; - case FieldDescriptor::TYPE_UINT32: - return "0"; // see notes for TYPE_FIXED32 - case FieldDescriptor::TYPE_UINT64: - return "0L"; // see notes for TYPE_FIXED64 - } -} string FieldGenerator::getInitValue() const { if (descriptor->is_repeated()) #ifndef KOTLIN_GENERATED_CODE_LANGUAGE_LEVEL_LOW @@ -138,13 +22,13 @@ string FieldGenerator::getInitValue() const { return "arrayOf()"; #endif - return protobufTypeToInitValue(descriptor); + return name_resolving::protobufTypeToInitValue(descriptor); } void FieldGenerator::generateCode(io::Printer *printer, bool isBuilder) const { map vars; vars["name"] = simpleName; - vars["field"] = protobufToKotlinField(); + vars["field"] = name_resolving::protobufToKotlinField(descriptor); printer->Print(vars, "var $name$ : $field$\n"); // make setter private @@ -168,8 +52,8 @@ FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerato , modifier(descriptor->label()) , enclosingClass(enclosingClass) , simpleName(descriptor->name()) - , underlyingType(protobufToKotlinType()) - , fullType(protobufToKotlinField()) + , underlyingType(name_resolving::protobufToKotlinType(descriptor)) + , fullType(name_resolving::protobufToKotlinField(descriptor)) , protoType(descriptor->type()) , fieldNumber(descriptor->number()) { } @@ -177,7 +61,7 @@ FieldGenerator::FieldGenerator(FieldDescriptor const * descriptor, ClassGenerato // TODO: long, complicated and messy method. Refactor it ASAP void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead, bool noTag) const { map vars; - vars["type"] = protobufTypeToKotlinFunctionSuffix(descriptor->type()) + (noTag ? "NoTag" : ""); + vars["type"] = name_resolving::protobufTypeToKotlinFunctionSuffix(descriptor->type()) + (noTag ? "NoTag" : ""); vars["fieldNumber"] = std::to_string(fieldNumber); vars["maybeFieldNumber"] = noTag ? "" : std::to_string(fieldNumber); vars["fieldName"] = simpleName; @@ -306,45 +190,6 @@ void FieldGenerator::generateSerializationCode(io::Printer *printer, bool isRead } } -// TODO: refactor in separate static class -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_MESSAGE: - return "Message"; - case FieldDescriptor::TYPE_BYTES: - return "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"; - } -} void FieldGenerator::generateSetter(io::Printer *printer) const { map vars; @@ -408,11 +253,11 @@ void FieldGenerator::generateRepeatedMethods(io::Printer * printer, bool isBuild } string FieldGenerator::getKotlinFunctionSuffix() const { - return protobufTypeToKotlinFunctionSuffix(descriptor->type()); + return name_resolving::protobufTypeToKotlinFunctionSuffix(descriptor->type()); } string FieldGenerator::getUnderlyingTypeInitValue() const { - return protobufTypeToInitValue(descriptor); + return name_resolving::protobufTypeToInitValue(descriptor); } } // namespace kotlin 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 f8381924dff..4ce6ea425a1 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 @@ -20,20 +20,8 @@ class ClassGenerator; // declared in kotlin_class_generator.h class FieldGenerator { private: FieldDescriptor const * descriptor; - string protobufToKotlinField() const; - string protobufToKotlinType () const; // TODO: refactor from field generator to some static utility namespace - /** - * 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; - string protobufTypeToInitValue(FieldDescriptor const * descriptor) const; void generateSetter(io::Printer * printer) const; void generateRepeatedMethods(io::Printer * printer, bool isBuilder) 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 d0ff147e446..f86eed8f361 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 @@ -3,6 +3,8 @@ // #include "kotlin_name_resolver.h" +#include + #include namespace google { @@ -29,6 +31,152 @@ string getKotlinOutputByProtoName(string protoName) { return justName + ".kt"; } +string protobufToKotlinType(FieldDescriptor const * descriptor) { + FieldDescriptor::Type type = descriptor->type(); + switch(type) { + case FieldDescriptor::TYPE_BOOL: + return "Boolean"; + case FieldDescriptor::TYPE_BYTES: + return "ByteArray"; + case FieldDescriptor::TYPE_DOUBLE: + return "Double"; + case FieldDescriptor::TYPE_ENUM: + return string(descriptor->enum_type()->name()); + case FieldDescriptor::TYPE_FIXED32: + // we map uint32 into Int, storing top bit in sign bit + return "Int"; + case FieldDescriptor::TYPE_FIXED64: + // we map uint64 into Long, storing top bit in sign bit + return "Long"; + case FieldDescriptor::TYPE_FLOAT: + return "Float"; + case FieldDescriptor::TYPE_INT32: + return "Int"; + case FieldDescriptor::TYPE_INT64: + return "Long"; + case FieldDescriptor::TYPE_MESSAGE: + return string(descriptor->message_type()->name()); + case FieldDescriptor::TYPE_SFIXED32: + return "Int"; + case FieldDescriptor::TYPE_SFIXED64: + return "Long"; + case FieldDescriptor::TYPE_SINT32: + return "Int"; + case FieldDescriptor::TYPE_SINT64: + return "Long"; + case FieldDescriptor::TYPE_STRING: + return "kotlin.String"; + case FieldDescriptor::TYPE_UINT32: + return "Int"; // see notes for TYPE_FIXED32 + case FieldDescriptor::TYPE_UINT64: + return "Long"; // see notes for TYPE_FIXED64 + } +} + +string protobufToKotlinField(FieldDescriptor const * descriptor) { + FieldDescriptor::Label modifier = descriptor->label(); + string preamble = "", + postamble = ""; + switch (modifier) { + case FieldDescriptor::LABEL_REQUIRED: + break; + case FieldDescriptor::LABEL_OPTIONAL: + postamble = "?"; + break; + case FieldDescriptor::LABEL_REPEATED: +#ifndef KOTLIN_GENERATED_CODE_LANGUAGE_LEVEL_LOW + preamble = "MutableList <"; + postamble = "> "; + break; +#else + preamble = "Array <"; + postamble = "> "; + break; +#endif + } + return preamble + protobufToKotlinType(descriptor) + postamble; +} + +string protobufTypeToInitValue(FieldDescriptor const * descriptor) { + FieldDescriptor::Type type = descriptor->type(); + switch(type) { + case FieldDescriptor::TYPE_BOOL: + return "false"; + case FieldDescriptor::TYPE_BYTES: + return "ByteArray(0)"; + case FieldDescriptor::TYPE_DOUBLE: + return "0.0"; + case FieldDescriptor::TYPE_ENUM: { + string enumType = descriptor->enum_type()->name(); + return enumType + ".fromIntTo" + enumType + "(0)"; // produce enum from 0, as demanded by Google + } + case FieldDescriptor::TYPE_FIXED32: + return "0"; + case FieldDescriptor::TYPE_FIXED64: + return "0L"; + case FieldDescriptor::TYPE_FLOAT: + return "0f"; + case FieldDescriptor::TYPE_INT32: + return "0"; + case FieldDescriptor::TYPE_INT64: + return "0L"; + case FieldDescriptor::TYPE_MESSAGE: + return string(descriptor->message_type()->name()) + "()"; + case FieldDescriptor::TYPE_SFIXED32: + return "0"; + case FieldDescriptor::TYPE_SFIXED64: + return "0L"; + case FieldDescriptor::TYPE_SINT32: + return "0"; + case FieldDescriptor::TYPE_SINT64: + return "0L"; + case FieldDescriptor::TYPE_STRING: + return "\"\""; + case FieldDescriptor::TYPE_UINT32: + return "0"; // see notes for TYPE_FIXED32 + case FieldDescriptor::TYPE_UINT64: + return "0L"; // see notes for TYPE_FIXED64 + } +} + +string protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type) { + 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_MESSAGE: + return "Message"; + case FieldDescriptor::TYPE_BYTES: + return "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 name_resolving } // namespace kotlin } // namespace compiler 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 ddf0453598b..112253c9451 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 @@ -6,6 +6,7 @@ #define GOOGLE_KOTLIN_NAME_RESOLVER_H #include +#include namespace google { namespace protobuf { @@ -19,6 +20,22 @@ std::string getFileNameWithoutExtension(std::string fullName); std::string getKotlinOutputByProtoName(std::string protoName); +std::string protobufTypeToInitValue(FieldDescriptor const * descriptor); + +std::string protobufToKotlinField(FieldDescriptor const * descriptor); + +std::string protobufToKotlinType(FieldDescriptor const * descriptor); + +/** +* 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) +*/ +std::string protobufTypeToKotlinFunctionSuffix(FieldDescriptor::Type type); + } // namespace name_resolving } // namespace kotlin } // namespace compiler