Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove importresolver package #5

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7beadd7
Use 4 spaces instead of 2 for default indent
pranjalvachaspati-toast Oct 12, 2021
5665e73
Remove message.stg
pranjalvachaspati-toast Oct 13, 2021
2cc5b3a
Remove Descriptor template
pranjalvachaspati-toast Oct 13, 2021
7ecc79f
Remove Descriptor template
pranjalvachaspati-toast Oct 13, 2021
14bd064
Remove dead code in header template and most of services template.
pranjalvachaspati-toast Oct 13, 2021
0861dcd
Set locale for decapitalize to get rid of compiler warning.
pranjalvachaspati-toast Oct 13, 2021
1cca8d0
Remove unused templates
pranjalvachaspati-toast Oct 13, 2021
151e25c
Create subpackage for annotators.
pranjalvachaspati-toast Oct 13, 2021
945b990
Merge branch 'kotlinpoet' of https://github.com/andrewparmet/protokt …
pranjalvachaspati-toast Oct 13, 2021
e24fb1d
Move methodType to kotlinpoet and get rid of services.stg
pranjalvachaspati-toast Oct 13, 2021
0369624
Remove Oneof stringtemplates.
pranjalvachaspati-toast Oct 13, 2021
5964ab4
Get rid of a couple renderers
pranjalvachaspati-toast Oct 13, 2021
46839ce
Migrate boxing & default value renderers away from StringTemplate.
pranjalvachaspati-toast Oct 14, 2021
f12ca3c
Remove sizeof stringtemplates.
pranjalvachaspati-toast Oct 15, 2021
9981c53
Add non-stringtemplate serializer generation
pranjalvachaspati-toast Oct 15, 2021
ec526a1
Get rid of renderers stringtemplate
pranjalvachaspati-toast Oct 15, 2021
91accd6
Remove options stringtemplate
pranjalvachaspati-toast Oct 15, 2021
8aec02e
--amend
pranjalvachaspati-toast Oct 15, 2021
8223782
Merge branch 'kotlinpoet' of https://github.com/andrewparmet/protokt …
pranjalvachaspati-toast Oct 15, 2021
4f4d40a
Convert deserializer to use kotlinpoet
pranjalvachaspati-toast Oct 16, 2021
d4af5e5
Create packages for import resolution and descriptor stuff
pranjalvachaspati-toast Oct 16, 2021
f38ffed
Create packages for import resolution and descriptor stuff
pranjalvachaspati-toast Oct 16, 2021
2125158
This merge required some additional changes - mostly changing Strings…
pranjalvachaspati-toast Oct 18, 2021
9b264a3
Additional changes from Strings to CodeBlocks
pranjalvachaspati-toast Oct 18, 2021
8bb76ce
Disable non-kotlinpoet import resolution
pranjalvachaspati-toast Oct 18, 2021
db9d992
Remove importresolution package
pranjalvachaspati-toast Oct 18, 2021
764782c
Merge branch 'kotlinpoet' of https://github.com/andrewparmet/protokt …
pranjalvachaspati-toast Oct 18, 2021
1f53989
Make fixes for PR comments
pranjalvachaspati-toast Oct 19, 2021
e84eae0
Use DSL typename in DeserializerAnnotator
pranjalvachaspati-toast Oct 19, 2021
a4193df
Remove dependency on stringtemplate
pranjalvachaspati-toast Oct 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ object versions {
const val kotlinxCoroutines = "1.3.9"
const val protobuf = DEFAULT_PROTOBUF_VERSION
const val protobufPlugin = "0.8.17"
const val stringTemplate = "4.3.1"

// Test
const val jackson = "2.13.0"
Expand Down Expand Up @@ -68,8 +67,6 @@ object libraries {
const val protobufLite = "com.google.protobuf:protobuf-javalite:${versions.protobuf}"
const val protoc = "com.google.protobuf:protoc:${versions.protobuf}"

const val stringTemplate = "org.antlr:ST4:${versions.stringTemplate}"

// Test
const val jackson = "com.fasterxml.jackson.module:jackson-module-kotlin:${versions.jackson}"
const val junit = "org.junit.jupiter:junit-jupiter:${versions.junit}"
Expand Down
1 change: 0 additions & 1 deletion protokt-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ dependencies {
implementation(libraries.kotlinReflect)
implementation(libraries.kotlinxCoroutinesCore)
implementation(libraries.protobufJava)
implementation(libraries.stringTemplate)

testImplementation(project(":testing:testing-util"))

Expand Down
4 changes: 1 addition & 3 deletions protokt-codegen/src/main/kotlin/com/toasttab/protokt/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ import com.google.protobuf.ExtensionRegistry
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse.Feature
import com.toasttab.protokt.codegen.descriptor.FileDescriptorResolver
import com.toasttab.protokt.codegen.impl.Accumulator
import com.toasttab.protokt.codegen.impl.FileDescriptorResolver
import com.toasttab.protokt.codegen.impl.ImportResolver
import com.toasttab.protokt.codegen.impl.resolvePackage
import com.toasttab.protokt.codegen.protoc.ProtocolContext
import com.toasttab.protokt.codegen.protoc.fileName
Expand Down Expand Up @@ -79,7 +78,6 @@ private fun generate(

return Accumulator.buildFile(
protocol,
ImportResolver.resolveImports(protocol),
FileDescriptorResolver.resolveFileDescriptor(protocol)
)?.toString()?.let(::tidy)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
* limitations under the License.
*/

package com.toasttab.protokt.codegen.impl
package com.toasttab.protokt.codegen.annotators

import com.github.andrewoma.dexx.kollection.immutableListOf
import com.squareup.kotlinpoet.TypeSpec
import com.toasttab.protokt.codegen.impl.MessageAnnotator.Companion.annotateMessage
import com.toasttab.protokt.codegen.impl.ServiceAnnotator.annotateService
import com.toasttab.protokt.codegen.annotators.MessageAnnotator.Companion.annotateMessage
import com.toasttab.protokt.codegen.annotators.ServiceAnnotator.annotateService
import com.toasttab.protokt.codegen.impl.EnumBuilder
import com.toasttab.protokt.codegen.model.PPackage
import com.toasttab.protokt.codegen.protoc.AnnotatedType
import com.toasttab.protokt.codegen.protoc.Enum
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
* limitations under the License.
*/

package com.toasttab.protokt.codegen.impl
package com.toasttab.protokt.codegen.annotators

import arrow.core.None
import arrow.core.Some
import com.squareup.kotlinpoet.TypeName
import com.toasttab.protokt.codegen.impl.Annotator.Context
import com.toasttab.protokt.codegen.annotators.Annotator.Context
import com.toasttab.protokt.codegen.impl.Wrapper.interceptMapKeyTypeName
import com.toasttab.protokt.codegen.impl.Wrapper.interceptMapValueTypeName
import com.toasttab.protokt.codegen.impl.resolvePackage
import com.toasttab.protokt.codegen.impl.stripEnclosingMessageNamePrefix
import com.toasttab.protokt.codegen.impl.stripRootMessageNamePrefix
import com.toasttab.protokt.codegen.protoc.FileDesc
import com.toasttab.protokt.codegen.protoc.MapEntry
import com.toasttab.protokt.codegen.protoc.Message
import com.toasttab.protokt.codegen.protoc.Oneof
import com.toasttab.protokt.codegen.protoc.Protocol
import com.toasttab.protokt.codegen.protoc.StandardField
import com.toasttab.protokt.codegen.template.Renderers.ConcatWithScope

fun resolveMapEntry(m: Message) =
MapEntry(
Expand All @@ -50,21 +50,9 @@ class MapTypeParams(

fun oneOfScope(f: Oneof, type: String, ctx: Context) =
ctx.stripEnclosingMessageNamePrefix(
ctx.stripRootMessageNamePrefix(
ConcatWithScope.render(
scope = type,
value = f.name
)
)
ctx.stripRootMessageNamePrefix("$type.${f.name}")
)

fun String.emptyToNone() =
if (isEmpty()) {
None
} else {
Some(this)
}

fun kotlinPackage(protocol: Protocol) =
kotlinPackage(protocol.desc)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package com.toasttab.protokt.codegen.impl
import arrow.core.Option
import arrow.core.firstOrNone
import arrow.core.toOption
import com.toasttab.protokt.codegen.impl.Annotator.Context
import com.toasttab.protokt.codegen.annotators.Annotator.Context
import com.toasttab.protokt.codegen.protoc.Message

internal fun Context.stripRootMessageNamePrefix(s: String) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,33 @@
* limitations under the License.
*/

package com.toasttab.protokt.codegen.impl
package com.toasttab.protokt.codegen.annotators

import arrow.core.None
import arrow.core.Option
import arrow.core.Some
import arrow.core.getOrElse
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.LambdaTypeName
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.asTypeName
import com.toasttab.protokt.codegen.impl.Annotator.Context
import com.toasttab.protokt.codegen.impl.MessageAnnotator.Companion.IDEAL_MAX_WIDTH
import com.toasttab.protokt.codegen.impl.PropertyAnnotator.Companion.annotateProperties
import com.squareup.kotlinpoet.buildCodeBlock
import com.toasttab.protokt.codegen.annotators.Annotator.Context
import com.toasttab.protokt.codegen.annotators.MessageAnnotator.Companion.IDEAL_MAX_WIDTH
import com.toasttab.protokt.codegen.annotators.PropertyAnnotator.Companion.annotateProperties
import com.toasttab.protokt.codegen.impl.Wrapper.interceptReadFn
import com.toasttab.protokt.codegen.impl.Wrapper.keyWrapped
import com.toasttab.protokt.codegen.impl.Wrapper.mapKeyConverter
import com.toasttab.protokt.codegen.impl.Wrapper.mapValueConverter
import com.toasttab.protokt.codegen.impl.Wrapper.valueWrapped
import com.toasttab.protokt.codegen.impl.Wrapper.wrapField
import com.toasttab.protokt.codegen.impl.Wrapper.wrapped
import com.toasttab.protokt.codegen.impl.Wrapper.wrapperName
import com.toasttab.protokt.codegen.impl.buildFunSpec
import com.toasttab.protokt.codegen.model.FieldType
import com.toasttab.protokt.codegen.protoc.Message
import com.toasttab.protokt.codegen.protoc.Oneof
Expand All @@ -44,18 +48,22 @@ import com.toasttab.protokt.codegen.protoc.Tag
import com.toasttab.protokt.codegen.template.Message.Message.DeserializerInfo
import com.toasttab.protokt.codegen.template.Message.Message.DeserializerInfo.Assignment
import com.toasttab.protokt.codegen.template.Message.Message.PropertyInfo
import com.toasttab.protokt.codegen.template.Renderers.Deserialize
import com.toasttab.protokt.codegen.template.Renderers.Deserialize.Options
import com.toasttab.protokt.codegen.template.Renderers.Read
import com.toasttab.protokt.rt.KtDeserializer
import com.toasttab.protokt.rt.KtMessageDeserializer
import com.toasttab.protokt.codegen.template.Oneof as OneofTemplate
import com.toasttab.protokt.rt.UnknownFieldSet

internal class DeserializerAnnotator
private constructor(
private val msg: Message,
private val ctx: Context
) {
/** Creates a {@see KtDeserializer<T>} companion object, where T is the Kotlin type for this Message.
*
* Contains functions:
* - deserialize(deserializer : KTMessageDeserializer) : T
* - invoke(dsl: ApiDsl.() -> Unit): Api
*
* */
private fun annotateDeserializer(): TypeSpec {
val deserializerInfo = annotateDeserializerOld()
val properties = annotateProperties(msg, ctx)
Expand All @@ -82,36 +90,24 @@ private constructor(
)
)
.addFunction(
FunSpec.builder("deserialize")
.addModifiers(KModifier.OVERRIDE)
.addParameter("deserializer", KtMessageDeserializer::class)
.returns(msg.typeName)
.addCode(
if (properties.isNotEmpty()) {
properties.joinToString("\n") { "var " + deserializeVar(it) } + "\n"
} else {
""
} +
"""
|var unknownFields: UnknownFieldSet.Builder? = null
|
|while (true) {
| when (deserializer.readTag()) {
| 0 ->
| return ${msg.name}(
| ${constructorLines(properties)}
| )
|${assignmentLines(deserializerInfo)}
| else ->
| unknownFields =
| (unknownFields ?: UnknownFieldSet.Builder()).also {
| it.add(deserializer.readUnknown())
| }
| }
|}
""".trimMargin()
)
.build()
buildFunSpec("deserialize") {

addModifiers(KModifier.OVERRIDE)
addParameter("deserializer", KtMessageDeserializer::class)
returns(msg.typeName)

if (properties.isNotEmpty()) {
properties.forEach { addStatement("var %L", deserializeVar(it)) }
}
addStatement("var unknownFields: %T? = null", UnknownFieldSet.Builder::class)
beginControlFlow("while (true)")
beginControlFlow("when(deserializer.readTag())")
addStatement("0 -> return·%N(%L)", msg.name, constructorLines(properties))
deserializerInfo.forEach() { addStatement("%L -> %L = %L", it.tag, it.assignment.fieldName, it.assignment.value) }
addStatement("else -> unknownFields = (unknownFields ?: %T.Builder()).also·{it.add(deserializer.readUnknown()) }", UnknownFieldSet::class)
endControlFlow()
endControlFlow()
}
)
.addFunction(
FunSpec.builder("invoke")
Expand All @@ -125,29 +121,16 @@ private constructor(
Unit::class.asTypeName()
)
)
.addCode("return ${msg.name}Dsl().apply(dsl).build()")
.addStatement("return %T().apply(dsl).build()", msg.dslTypeName)
.build()
)
.build()
}

private fun constructorLines(properties: List<PropertyInfo>) =
properties.joinToString("") {
deserializeWrapper(it) + ",\n "
} + "UnknownFieldSet.from(unknownFields)"

private fun assignmentLines(deserializerInfo: List<DeserializerInfo>) =
deserializerInfo.joinToString("\n") {
if (it.repeated) {
"""
| ${it.tag} ->
| ${it.assignment.fieldName} =
| ${it.assignment.value}
""".trimMargin()
} else {
" ${it.tag} -> ${it.assignment.fieldName} = ${it.assignment.value}"
}
}
private fun constructorLines(properties: List<PropertyInfo>) = buildCodeBlock {
properties.forEach() { add("%L,\n", deserializeWrapper(it)) }
add("%T.from(unknownFields)", UnknownFieldSet::class)
}

private fun annotateDeserializerOld(): List<DeserializerInfo> =
msg.flattenedSortedFields().flatMap { (field, oneOf) ->
Expand Down Expand Up @@ -193,7 +176,7 @@ private constructor(
4 + // when (...)
field.tag.toString().length +
4 + // ` -> `
field.name.length +
field.fieldName.length +
3 // ` = `

val spaceLeft = IDEAL_MAX_WIDTH - spaceTaken
Expand All @@ -217,32 +200,58 @@ private constructor(
)

private fun oneofDes(f: Oneof, ff: StandardField) =
OneofTemplate.Deserialize.render(
oneof = f.name,
name = f.fieldTypeNames.getValue(ff.name),
read = deserializeString(ff, ctx, false)
)
"${f.name}.${f.fieldTypeNames.getValue(ff.fieldName)}(${deserializeString(ff, ctx, false)})"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yikes. (I know this came straight from StringTemplate.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, there are a few messy templates in here that should probably be cleaned up and kotlinpoet-ified.


companion object {
fun annotateDeserializer(msg: Message, ctx: Context) =
DeserializerAnnotator(msg, ctx).annotateDeserializer()
}
}

fun deserializeString(f: StandardField, ctx: Context, packed: Boolean) =
Deserialize.render(
field = f,
read = interceptReadFn(f, f.readFn()),
lhs = f.fieldName,
packed = packed,
options = deserializeOptions(f, ctx)
)
fun deserializeString(f: StandardField, ctx: Context, packed: Boolean): String {
val options = deserializeOptions(f, ctx)
val read = CodeBlock.of("deserializer.%L", interceptReadFn(f, f.readFn()))
val wrappedRead = options?.let { wrapField(it.wrapName, read, it.type, it.oneof) } ?: read.toString()
return when {
f.map -> deserializeMap(f, options, read)
f.repeated -> """
|(${f.fieldName} ?: mutableListOf()).apply·{
| deserializer.readRepeated($packed)·{
| add($wrappedRead)
| }
| }
""".trimMargin()
else -> wrappedRead.toString()
}
}

fun deserializeMap(f: StandardField, options: Options?, read: CodeBlock): String {
val key = options?.keyWrap?.let { wrapField(it, CodeBlock.of("it.key"), options.type, options.oneof) } ?: CodeBlock.of("it.key")
val value = options?.valueWrap?.let { wrapField(it, CodeBlock.of("it.value"), options.valueType, options.oneof) } ?: CodeBlock.of("it.value")
return """
|(${f.fieldName} ?: mutableMapOf()).apply·{
| deserializer.readRepeated(false)·{
| $read
| .let { put(
| $key,
| $value
| ) }
| }
| }
""".trimMargin()
}

private fun StandardField.readFn() =
Read.render(
type = type,
builder = readFnBuilder(type)
)
when (type) {
FieldType.SFIXED32 -> "readSFixed32()"
FieldType.SFIXED64 -> "readSFixed64()"
FieldType.SINT32 -> "readSInt32()"
FieldType.SINT64 -> "readSInt64()"
FieldType.UINT32 -> "readUInt32()"
FieldType.UINT64 -> "readUInt64()"
// by default for DOUBLE we get readDouble, for BOOL we get readBool(), etc.
else -> "read${type.name.toLowerCase().capitalize()}(${readFnBuilder(type)})"
}

private fun StandardField.readFnBuilder(type: FieldType) =
when (type) {
Expand All @@ -257,9 +266,18 @@ private fun deserializeOptions(f: StandardField, ctx: Context) =
keyWrap = mapKeyConverter(f, ctx)?.toString(),
valueWrap = mapValueConverter(f, ctx)?.toString(),
valueType = f.mapEntry?.value?.type,
type = f.type.toString(),
type = f.type,
oneof = true
)
} else {
null
}

class Options(
val wrapName: String,
val keyWrap: String?,
val valueWrap: String?,
val valueType: FieldType?,
val type: FieldType,
val oneof: Boolean
)
Loading