Open darronschall opened 1 year ago
Now that Kotlin 1.8 added the @ObjCName
annotation, I'm thinking the best solution would be for pbandk to read the objc_class_prefix
and swift_prefix
options (see https://github.com/protocolbuffers/protobuf/blob/b4811c3ffb6c7d259e5771822918db8a1eb52f7f/src/google/protobuf/descriptor.proto#L429 for the option definitions) from the proto file and translate those into appropriate @ObjCName.name
and @ObjCName.swiftName
annotations.
We can now also have pbandk use the @ObjCName
annotation to implement the default behavior documented for the swift_prefix
option when the option is not explicitly provided:
// By default Swift generators will take the proto package and CamelCase it // replacing '.' with underscore and use that to prefix the types/symbols // defined.
@darronschall would the above two changes address your use case?
@garyp Nice suggestion, that solves the problem elegantly. Thanks!
I've got some other large pbandk changes in the queue, so I won't be able to work on this soon. Pull requests are always welcome though 😃 I think this should be a relatively straightforward change in CodeGenerator
to add the new annotations. I'm happy to provide pointers.
Thanks @garyp! I took a look at CodeGenerator
, and while I'm not familiar with this code base I can see where the code should be modified to output the Kotlin 1.8 annotations.
The biggest question I have off-hand is: Do I need to do anything special to grab the swift_prefix
or objc_class_prefix
values form the proto file? I see these are FieldDescriptors here and here. I'm assuming this is pass-through from protoc
and I don't need to do any parsing, but I'm unclear at the moment on how I would access the values within CodeGenerator
. Possibly from File? But nothing there is jumping out at me either.
If you know the answer off the top of your head, great! If not, I can dive in when I get some time and play around with it.
@darronschall You'll need to add new fields to that File
type to contain the Swift and ObjC prefixes. Take a look at FileBuilder.buildFile()
(https://github.com/streem/pbandk/blob/f948160a396d82d890f5ce62bd262595871d1e40/protoc-gen-pbandk/lib/src/commonMain/kotlin/pbandk/gen/FileBuilder.kt#L10) to see how the File
instance is constructed. You'll need to grab the values of ctx.fileDesc.options?.swiftPrefix
and ctx.fileDesc.options?.objcClassPrefix
.
Once you have the values added to File
, you can access them from inside of CodeGenerator
.
I'm using PBandK to generate the networking layer in a Kotlin Multiplatform Mobile project (iOS/Android apps) with the help of a service-gen plugin I open-sourced at https://github.com/collectiveidea/twirp-kmm.
Due to the lack of packages in Objective-C, Kotlin/Native renames classes that share the same name by appending underscores to avoid name collisions. This presents issues when protobuf message classes share the same class name as client-side models. For example, if protobuf defines an
example.api.Item
message but there also exists anexample.model.Item
model class, Kotlin/Native renames one of them toItem_
so that both classes can be used in Swift code. Working withItem_
andItem
is both confusing and unpleasant. There is a feature request at https://youtrack.jetbrains.com/issue/KT-50767/Kotlin-Native-Objective-C-Stable-rename-algorithm-for-classes-with-same-name to improve Kotlin/Native support for this scenario, which suggests a new@SwiftName
annotation to improve interop, but no timeframe is given on implementing it.Ideally, PBandK would allow an option to append a suffix to protobuf messages during the generation process. Something like
message_suffix
(commonlyDTO
in this context):This would cause the protobuf
message Example
to be generated as@pbandk.Export public data class ExampleDTO
. The suffix would not apply to messages ending inRequest
orResponse
. In the future, should Kotlin/Native introduce@SwiftName
per the linked Youtrack, then the suffix option might instead generate@pbandk.Export @SwiftName("ExampleDTO") public data class Example
. EDIT: Kotlin/Native 1.8.0 adds a@ObjCName
annotation that the generated code can leverage.This is a problem that I needed to solve in the short-term. As a workaround, I've created a small bash script that pre-processes my project's protobuf file to append the
DTO
suffix to messages before running the PBandK code-gen. The net result is the that the generated code appendsDTO
to the message class names. My (macOS) script looks roughly like this (for anyone else running into the same issue):