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

Include type alias annotations in SerialDescriptor.annotations #2702

Open
Laxystem opened this issue Jun 5, 2024 · 12 comments
Open

Include type alias annotations in SerialDescriptor.annotations #2702

Laxystem opened this issue Jun 5, 2024 · 12 comments
Labels

Comments

@Laxystem
Copy link

Laxystem commented Jun 5, 2024

I've only seen documentation for .PROPERTY and .CLASS.

@sandwwraith
Copy link
Member

No, we currently do not support @SerialInfo-annotations used on types.

@Laxystem
Copy link
Author

Laxystem commented Jun 5, 2024

No, we currently do not support @SerialInfo-annotations used on types.

Ic. Ig this issue has now become a feature request - to support @SerialInfo annotations on TYPE_ALIASes or TYPEs.

@pdvrieze
Copy link
Contributor

pdvrieze commented Jun 5, 2024

To implement this would require updates to SerialDescriptor (in the library) and the compiler plugin. As such it might be helpful to know what your use case is, and what your intended semantics are:

  • For a type alias is the annotation to be understood to be: on the property using the alias; on the class itself; or some third form (note that both of the first two options come with their own challenges)
  • If it is a generic type parameter, how are you going to expose that?

Considering that the serial descriptor is linked to the serializer what you are effectively asking for is some sort of lightweight custom serializer (there is a naming problem here as well - names are supposed to be unique, and some format rely on that fact for caching)

@Laxystem
Copy link
Author

Laxystem commented Jun 5, 2024

As such it might be helpful to know what your use case is, and what your intended semantics are:

public typealias LangString = @NonLinkedJson(wrapWithValueObject = false) @Serializable(with = LangStringSerializer::class) ImmutableMap<Locale?, ImmutableList<String>>

Because it's much more flexible than creating a value class.

If it is a generic type parameter, how are you going to expose that?
There is a naming problem here as well - names are supposed to be unique, and some format rely on that fact for caching.

One could support type aliases, instead of types, and then just use the typealias' name.

@Laxystem
Copy link
Author

Laxystem commented Jun 5, 2024

An alternative would be to support an annotations parameter on SerialDescriptor(serialName: String, original: SerialDescriptor).

@pdvrieze
Copy link
Contributor

pdvrieze commented Jun 5, 2024

@Laxystem You can already use buildSerialDescriptor to build fully custom descriptors (including ones that just copy from the original) - even implementing the interface works (yes I'm aware these are hidden behind experimental flags - this is out of caution, to allow for API changes, not because the feature is going to suddenly disappear). Then you can have (LinkedLangStringSerializer and NonlinkedLangStringSerializer)

@Laxystem
Copy link
Author

Laxystem commented Jun 8, 2024

@Laxystem You can already use buildSerialDescriptor to build fully custom descriptors (including ones that just copy from the original) - even implementing the interface works (yes I'm aware these are hidden behind experimental flags - this is out of caution, to allow for API changes, not because the feature is going to suddenly disappear). Then you can have (LinkedLangStringSerializer and NonlinkedLangStringSerializer)

Ic, thanks. I'll keep this open as a feature request though

@Laxystem Laxystem changed the title Question: Do AnnotationTarget.TYPE annotations appear in SerialDescriptor.annotations? Include type alias annotations in SerialDescriptor.annotations Jun 8, 2024
@sandwwraith
Copy link
Member

The problem with this feature is that in case of usages like

@Serializable
class X

@Serializable
class A(val s: List<@SomeInfo X>, val e: List<@SomeOtherInfo X>)

Serial descriptor for X is not created every time, it is simply taken from X.serializer(), because it is constructed and filled there. It is possible to come up with some technical solution to re-wrap it with some additional annotation info of course, but it is a lot of work for such a narrow-scoped feature

@Laxystem
Copy link
Author

Laxystem commented Jun 16, 2024

Serial descriptor for X is not created every time, it is simply taken from X.serializer(), because it is constructed and filled there. It is possible to come up with some technical solution to re-wrap it with some additional annotation info of course, but it is a lot of work for such a narrow-scoped feature

That's why I'm proposing to support type aliases and not all types.

typealias XWithInfo = @SomeInfo X

// compiles into

typealias XWithInfo = @Serializable(XWithInfoSerializer::class) X

object XWithInfoSerializer : KSerializer<X> by serializer<X>() {
    override val descriptor = this@KSerializer.descriptor.withAnnotation(SomeInfo())
}

// which in turn compiles into replacing all usages of XWithInfo with @Serializable(XWithInfoSerializer::class) X

@sandwwraith
Copy link
Member

Type aliases aren't really compiled into anything, they just dissolve into thin air :) I'm not sure if it is possible to provide such substitution with a compiler plugin

@Laxystem
Copy link
Author

Type aliases aren't really compiled into anything, they just dissolve into thin air :) I'm not sure if it is possible to provide such substitution with a compiler plugin

That's the thing, what I'm suggesting is to create custom serializers with the typealias' serial name, that way, you have no conflicts.

@pdvrieze
Copy link
Contributor

typealias XWithInfo = @SomeInfo X

// compiles into

typealias XWithInfo = @Serializable(XWithInfoSerializer::class) X

This would be like an extension of MetaSerializable (like the custom/serializer factory behaviour originally discussed when that annotation was introduced).

object XWithInfoSerializer : KSerializer<X> by serializer<X>() {
    override val descriptor = [email protected](SomeInfo())
}

This is not actually valid, the descriptor must have a unique serialName. I'm also not sure that the SomeInfo annotation needs to be attached to the type/serializer rather than the use site.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants