Skip to content

Add checks and error messages for ProtoUnknownFields annotation#5755

Open
xiaozhikang0916 wants to merge 5 commits intoJetBrains:masterfrom
xiaozhikang0916:xzk/serialization-protobuf-unknown-check
Open

Add checks and error messages for ProtoUnknownFields annotation#5755
xiaozhikang0916 wants to merge 5 commits intoJetBrains:masterfrom
xiaozhikang0916:xzk/serialization-protobuf-unknown-check

Conversation

@xiaozhikang0916
Copy link

A following up pull request for Kotlin/kotlinx.serialization/pull/2860 to check whether a class is matching these limitations when using @ProtoUnknownFields

  1. There is no more than 1 field annotated with @ProtoUnknownFields
  2. Type of field annotated with @ProtoUnknownFields should be ProtoUnknownFieldHolder
  3. Non-null field of @ProtoUnknownFields should have default value ProtoUnknownFieldHolder.Empty

Build and test passed locally via ./gradlew :kotlinx-serialization-compiler-plugin:test

@kotlin-safe-merge
Copy link

Code Owners

Rule Owners Approval
/​plugins/​kotlinx-​serialization/​ @sandwwraith, @shanshin
/​plugins/​kotlinx-​serialization/​kotlinx-​serialization.​k2/​src/​org/​jetbrains/​kotlinx/​serialization/​compiler/​fir/​checkers/​KtDefaultErrorMessagesSerialization.​kt @bnorm, @cypressious, @ligee, @serras
*Generated.​java


DiagnosticFactory2<KtAnnotationEntry, String, String> PROTOBUF_PROTO_NUM_DUPLICATED = DiagnosticFactory2.create(WARNING);

DiagnosticFactory2<KtAnnotationEntry, String, String> PROTO_UNKNOWN_FIELDS_MULTIPLE_ANNOTATIONS = DiagnosticFactory2.create(ERROR);
Copy link
Contributor

Choose a reason for hiding this comment

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

@sandwwraith, should we also add these checks into K1?

reporter: DiagnosticReporter,
) {
val annotatedProps = mutableListOf<FirPropertySymbol>()
classSymbol.processAllDeclarations(session) { member ->
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use properties.serializableProperties here?

)
map.put(
FirSerializationErrors.PROTO_UNKNOWN_FIELDS_MULTIPLE_ANNOTATIONS,
"In class ''{0}'', fields annotated with @ProtoUnknownFields: ''{1}''; only one field per class is allowed.",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's better to start with the cause of the error, like
"@ProtoUnknownFields must not be present on more than one property, specified on {0} in class {1}".
Same for the other messages.

@sandwwraith, WDYT?


@SerialInfo
@Target(AnnotationTarget.PROPERTY)
public annotation class ProtoUnknownFields
Copy link
Contributor

Choose a reason for hiding this comment

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

@sandwwraith, is there a way to remind ourselves to delete these classes when the serialization runtime is updated?

Copy link
Author

Choose a reason for hiding this comment

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

Should I mark this pr as draft and remove them after Kotlin/kotlinx.serialization#2860 is merged?


// OK: non-nullable with default value
@Serializable
data class ValidNonNullable(@ProtoUnknownFields val unknown: <!SERIALIZER_NOT_FOUND!>ProtoUnknownFieldHolder<!> = ProtoUnknownFieldHolder.Empty)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's create a dummy serializer for the tests?
After a while, it will be hard to remember why error SERIALIZER_NOT_FOUND is expected. Especially after updating the runtime

val protoOneOfAnnotationClassId = ClassId.topLevel(protoOneOfAnnotationFqName)

val protoUnknownFieldsAnnotationClassId = ClassId.topLevel(protoUnknownFieldsAnnotationFqName)
val protoUnknownFieldHolderClassId = ClassId(FqName("kotlinx.serialization.protobuf"), Name.identifier("ProtoUnknownFieldHolder"))
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency let's create ...qName property for this class name

xiaozhikang0916 and others added 4 commits March 21, 2026 15:58
Add a dummy KSerializer implementation for ProtoUnknownFieldHolder to
avoid SERIALIZER_NOT_FOUND errors in tests. This makes the test intent
clearer and more maintainable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants