Skip to content

Commit 801fab2

Browse files
authored
Added support for Well-Known Types (#449)
1 parent 2130297 commit 801fab2

File tree

45 files changed

+3975
-208
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3975
-208
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Verify Protobuf Well-Known Types are Up-to-Date
2+
3+
on:
4+
pull_request:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
verify-platforms-table:
11+
name: Run Verification
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout Sources
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
- name: Setup Gradle
19+
uses: gradle/actions/setup-gradle@v4
20+
- name: Run Protobuf Conformance Test Generation
21+
run: ./gradlew :protobuf:protobuf-core:bufGenerateCommonMain --info --stacktrace
22+
- name: Check if Well-Known Types are up-to-date
23+
run: |
24+
if [[ -n "$(git status --porcelain | grep protobuf/protobuf-core/)" ]]; then
25+
echo "Well-Known Types are not up-to-date. Please run './gradlew :protobuf:protobuf-core:bufGenerateCommonMain' and commit changes"
26+
exit 1
27+
fi

gradle-plugin/api/gradle-plugin.api

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ public class kotlinx/rpc/RpcStrictModeExtension {
3939

4040
public final class kotlinx/rpc/VersionsKt {
4141
public static final field BUF_TOOL_VERSION Ljava/lang/String;
42-
public static final field GRPC_KOTLIN_VERSION Ljava/lang/String;
43-
public static final field GRPC_VERSION Ljava/lang/String;
4442
public static final field LIBRARY_VERSION Ljava/lang/String;
45-
public static final field PLUGIN_VERSION Ljava/lang/String;
46-
public static final field PROTOBUF_VERSION Ljava/lang/String;
4743
}
4844

4945
public class kotlinx/rpc/buf/BufExtension {
@@ -179,17 +175,15 @@ public final class kotlinx/rpc/protoc/ProcessProtoFilesKt$inlined$sam$i$org_grad
179175

180176
public abstract interface class kotlinx/rpc/protoc/ProtoSourceSet {
181177
public abstract fun getName ()Ljava/lang/String;
178+
public abstract fun getPlugins ()Lorg/gradle/api/NamedDomainObjectContainer;
182179
public abstract fun getProto ()Lorg/gradle/api/file/SourceDirectorySet;
180+
public abstract fun plugins (Lorg/gradle/api/Action;)V
183181
public fun proto (Lorg/gradle/api/Action;)V
184-
public abstract fun protocPlugin (Lkotlinx/rpc/protoc/ProtocPlugin;)V
185-
public abstract fun protocPlugin (Lorg/gradle/api/NamedDomainObjectProvider;)V
186182
}
187183

188184
public abstract interface class kotlinx/rpc/protoc/ProtocExtension {
189185
public abstract fun buf (Lorg/gradle/api/Action;)V
190186
public abstract fun getBuf ()Lkotlinx/rpc/buf/BufExtension;
191-
public abstract fun getPlugins ()Lorg/gradle/api/NamedDomainObjectContainer;
192-
public abstract fun plugins (Lorg/gradle/api/Action;)V
193187
}
194188

195189
public class kotlinx/rpc/protoc/ProtocPlugin {

gradle-plugin/src/main/kotlin/kotlinx/rpc/buf/tasks/BufGenerateTask.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public abstract class BufGenerateTask : BufExecTask() {
5656
/**
5757
* Whether to include Well-Known Types.
5858
*
59+
* Automatically sets [includeImports] to `true`.
60+
*
5961
* @see <a href="https://buf.build/docs/reference/cli/buf/generate/#include-wkt">buf generate --include-wkt</a>
6062
* @see [BufGenerateExtension.includeWkt]
6163
*/
@@ -91,7 +93,7 @@ public abstract class BufGenerateTask : BufExecTask() {
9193
buildList {
9294
add("--output"); add(outputDirectory.get().absolutePath)
9395

94-
if (includeImports.get()) {
96+
if (includeImports.get() || includeWkt.get()) {
9597
add("--include-imports")
9698
}
9799

gradle-plugin/src/main/kotlin/kotlinx/rpc/internal/configureLocalProtocGenDevelopmentDependency.kt

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,40 @@ package kotlinx.rpc.internal
77
import kotlinx.rpc.buf.tasks.BufGenerateTask
88
import kotlinx.rpc.protoc.grpcKotlinMultiplatform
99
import kotlinx.rpc.protoc.kotlinMultiplatform
10+
import kotlinx.rpc.protoc.protoSourceSets
1011
import kotlinx.rpc.rpcExtension
1112
import org.gradle.api.Project
1213
import org.gradle.internal.extensions.core.extra
1314
import org.gradle.kotlin.dsl.provideDelegate
1415
import org.gradle.kotlin.dsl.withType
1516

1617
@InternalRpcApi
17-
public fun Project.configureLocalProtocGenDevelopmentDependency() {
18+
public fun Project.configureLocalProtocGenDevelopmentDependency(
19+
vararg sourceSetSuffix: String = arrayOf("Test"),
20+
) {
1821
val globalRootDir: String by extra
1922

20-
rpcExtension().protoc.plugins {
21-
kotlinMultiplatform {
22-
local {
23-
javaJar("$globalRootDir/protoc-gen/protobuf/build/libs/protobuf-$version-all.jar")
23+
// init
24+
rpcExtension().protoc()
25+
26+
protoSourceSets.all {
27+
plugins {
28+
kotlinMultiplatform {
29+
local {
30+
javaJar("$globalRootDir/protoc-gen/protobuf/build/libs/protobuf-$version-all.jar")
31+
}
2432
}
25-
}
2633

27-
grpcKotlinMultiplatform {
28-
local {
29-
javaJar("$globalRootDir/protoc-gen/grpc/build/libs/grpc-$version-all.jar")
34+
grpcKotlinMultiplatform {
35+
local {
36+
javaJar("$globalRootDir/protoc-gen/grpc/build/libs/grpc-$version-all.jar")
37+
}
3038
}
3139
}
3240
}
3341

3442
tasks.withType<BufGenerateTask>().configureEach {
35-
if (name.endsWith("Test")) {
43+
if (sourceSetSuffix.any { name.endsWith(it) }) {
3644
val includedBuild = gradle.includedBuild("protoc-gen")
3745
dependsOn(includedBuild.task(":grpc:jar"))
3846
dependsOn(includedBuild.task(":protobuf:jar"))

gradle-plugin/src/main/kotlin/kotlinx/rpc/protoc/DefaultProtoSourceSet.kt

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package kotlinx.rpc.protoc
66

77
import kotlinx.rpc.buf.tasks.BufGenerateTask
8+
import kotlinx.rpc.protoc.ProtocPlugin.Companion.GRPC_KOTLIN_MULTIPLATFORM
9+
import kotlinx.rpc.protoc.ProtocPlugin.Companion.KOTLIN_MULTIPLATFORM
810
import kotlinx.rpc.util.findOrCreate
911
import kotlinx.rpc.util.withKotlinJvmExtension
1012
import kotlinx.rpc.util.withKotlinKmpExtension
@@ -17,6 +19,9 @@ import org.gradle.api.tasks.SourceSetContainer
1719
import org.gradle.kotlin.dsl.add
1820
import org.gradle.kotlin.dsl.listProperty
1921
import org.gradle.kotlin.dsl.property
22+
import org.gradle.kotlin.dsl.the
23+
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
24+
import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension
2025
import javax.inject.Inject
2126

2227
@Suppress("UNCHECKED_CAST")
@@ -34,18 +39,48 @@ internal open class DefaultProtoSourceSet @Inject constructor(
3439
internal val project: Project,
3540
override val name: String,
3641
) : ProtoSourceSet {
37-
val languageSourceSets: ListProperty<Any> = project.objects.listProperty<Any>()
38-
val protocPlugins: ListProperty<String> = project.objects.listProperty<String>().convention(emptyList())
39-
val generateTask: Property<BufGenerateTask> = project.objects.property<BufGenerateTask>()
42+
override val plugins: NamedDomainObjectContainer<ProtocPlugin> =
43+
project.objects.domainObjectContainer(ProtocPlugin::class.java) { name ->
44+
ProtocPlugin(name, project)
45+
}
4046

41-
override fun protocPlugin(plugin: NamedDomainObjectProvider<ProtocPlugin>) {
42-
protocPlugins.add(plugin.name)
47+
override fun plugins(action: Action<NamedDomainObjectContainer<ProtocPlugin>>) {
48+
action.execute(plugins)
4349
}
4450

45-
override fun protocPlugin(plugin: ProtocPlugin) {
46-
protocPlugins.add(plugin.name)
51+
init {
52+
val explicitApiModeEnabled = project.provider {
53+
project.the<KotlinBaseExtension>().explicitApi != ExplicitApiMode.Disabled
54+
}
55+
56+
plugins.create(KOTLIN_MULTIPLATFORM) {
57+
local {
58+
javaJar(project.kotlinMultiplatformProtocPluginJarPath)
59+
}
60+
61+
options.put("debugOutput", "protoc-gen-kotlin-multiplatform.log")
62+
63+
if (this@DefaultProtoSourceSet.name.lowercase().endsWith("main")) {
64+
options.put("explicitApiModeEnabled", explicitApiModeEnabled)
65+
}
66+
}
67+
68+
plugins.create(GRPC_KOTLIN_MULTIPLATFORM) {
69+
local {
70+
javaJar(project.grpcKotlinMultiplatformProtocPluginJarPath)
71+
}
72+
73+
options.put("debugOutput", "protoc-gen-grpc-kotlin-multiplatform.log")
74+
75+
if (this@DefaultProtoSourceSet.name.lowercase().endsWith("main")) {
76+
options.put("explicitApiModeEnabled", explicitApiModeEnabled)
77+
}
78+
}
4779
}
4880

81+
val languageSourceSets: ListProperty<Any> = project.objects.listProperty<Any>()
82+
val generateTask: Property<BufGenerateTask> = project.objects.property<BufGenerateTask>()
83+
4984
override val proto: SourceDirectorySet = project.objects.sourceDirectorySet(
5085
PROTO_SOURCE_DIRECTORY_NAME,
5186
"Proto sources",

gradle-plugin/src/main/kotlin/kotlinx/rpc/protoc/DefaultProtocExtension.kt

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@ import kotlinx.rpc.buf.tasks.registerBufExecTask
1313
import kotlinx.rpc.buf.tasks.registerBufGenerateTask
1414
import kotlinx.rpc.buf.tasks.registerGenerateBufGenYamlTask
1515
import kotlinx.rpc.buf.tasks.registerGenerateBufYamlTask
16-
import kotlinx.rpc.protoc.ProtocPlugin.Companion.GRPC_KOTLIN_MULTIPLATFORM
17-
import kotlinx.rpc.protoc.ProtocPlugin.Companion.KOTLIN_MULTIPLATFORM
1816
import kotlinx.rpc.util.ensureDirectoryExists
1917
import org.gradle.api.Action
2018
import org.gradle.api.GradleException
21-
import org.gradle.api.NamedDomainObjectContainer
2219
import org.gradle.api.Project
2320
import org.gradle.api.file.ConfigurableFileTree
2421
import org.gradle.api.model.ObjectFactory
@@ -41,15 +38,6 @@ internal open class DefaultProtocExtension @Inject constructor(
4138
objects: ObjectFactory,
4239
private val project: Project,
4340
) : ProtocExtension {
44-
override val plugins: NamedDomainObjectContainer<ProtocPlugin> =
45-
objects.domainObjectContainer(ProtocPlugin::class.java) { name ->
46-
ProtocPlugin(name, project)
47-
}
48-
49-
override fun plugins(action: Action<NamedDomainObjectContainer<ProtocPlugin>>) {
50-
action.execute(plugins)
51-
}
52-
5341
override val buf: BufExtension = project.objects.newInstance<BufExtension>()
5442
override fun buf(action: Action<BufExtension>) {
5543
action.execute(buf)
@@ -60,13 +48,10 @@ internal open class DefaultProtocExtension @Inject constructor(
6048
project.configureKotlinMultiplatformPluginJarConfiguration()
6149
project.configureGrpcKotlinMultiplatformPluginJarConfiguration()
6250

63-
createDefaultProtocPlugins()
64-
65-
project.protoSourceSets.all {
66-
protocPlugin(plugins.kotlinMultiplatform)
67-
protocPlugin(plugins.grpcKotlinMultiplatform)
68-
}
69-
51+
// ignore for bufGenerate task caching
52+
project.normalization.runtimeClasspath.ignore("**/protoc-gen-kotlin-multiplatform.log")
53+
project.normalization.runtimeClasspath.ignore("**/protoc-gen-grpc-kotlin-multiplatform.log")
54+
project.normalization.runtimeClasspath.ignore("**/.keep")
7055

7156
project.protoSourceSets.all {
7257
if (this !is DefaultProtoSourceSet) {
@@ -92,16 +77,8 @@ internal open class DefaultProtocExtension @Inject constructor(
9277

9378
val pairSourceSet = protoSourceSet.correspondingMainSourceSetOrNull()
9479

95-
val mainProtocPlugins = pairSourceSet?.protocPlugins ?: provider { emptyList() }
96-
val protocPluginNames = protoSourceSet.protocPlugins
97-
.zip(mainProtocPlugins) { left, right -> left + right }
98-
.map { it.distinct() }
99-
100-
val includedProtocPlugins = protocPluginNames.map { list ->
101-
list.map { pluginName ->
102-
this@DefaultProtocExtension.plugins.findByName(pluginName)
103-
?: throw GradleException("Protoc plugin $pluginName not found")
104-
}
80+
val includedProtocPlugins = provider {
81+
protoSourceSet.plugins.distinct()
10582
}
10683

10784
val protoFiles = protoSourceSet.proto
@@ -303,35 +280,6 @@ internal open class DefaultProtocExtension @Inject constructor(
303280
}
304281
}
305282

306-
private fun createDefaultProtocPlugins() {
307-
val explicitApiModeEnabled = project.provider {
308-
project.the<KotlinBaseExtension>().explicitApi != ExplicitApiMode.Disabled
309-
}
310-
311-
plugins.create(KOTLIN_MULTIPLATFORM) {
312-
local {
313-
javaJar(project.kotlinMultiplatformProtocPluginJarPath)
314-
}
315-
316-
options.put("debugOutput", "protoc-gen-kotlin-multiplatform.log")
317-
options.put("explicitApiModeEnabled", explicitApiModeEnabled)
318-
}
319-
320-
plugins.create(GRPC_KOTLIN_MULTIPLATFORM) {
321-
local {
322-
javaJar(project.grpcKotlinMultiplatformProtocPluginJarPath)
323-
}
324-
325-
options.put("debugOutput", "protoc-gen-grpc-kotlin-multiplatform.log")
326-
options.put("explicitApiModeEnabled", explicitApiModeEnabled)
327-
}
328-
329-
// ignore for bufGenerate task caching
330-
project.normalization.runtimeClasspath.ignore("**/protoc-gen-kotlin-multiplatform.log")
331-
project.normalization.runtimeClasspath.ignore("**/protoc-gen-grpc-kotlin-multiplatform.log")
332-
project.normalization.runtimeClasspath.ignore("**/.keep")
333-
}
334-
335283
private fun DefaultProtoSourceSet.correspondingMainSourceSetOrNull(): DefaultProtoSourceSet? {
336284
return when {
337285
name.lowercase().endsWith("main") -> {

gradle-plugin/src/main/kotlin/kotlinx/rpc/protoc/ProtoSourceSet.kt

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,14 @@ public interface ProtoSourceSet {
2121
public val name: String
2222

2323
/**
24-
* Adds a new protoc plugin.
25-
*
26-
* Example:
27-
* ```kotlin
28-
* protocPlugin(rpc.protoc.plugins.myPlugin)
29-
* ```
24+
* Container of protoc plugins to be applied to the source set.
3025
*/
31-
public fun protocPlugin(plugin: NamedDomainObjectProvider<ProtocPlugin>)
26+
public val plugins: NamedDomainObjectContainer<ProtocPlugin>
3227

3328
/**
34-
* Adds a new protoc plugin.
35-
*
36-
* Example:
37-
* ```kotlin
38-
* protocPlugin(rpc.protoc.plugins.myPlugin.get())
39-
* ```
29+
* Configures the protoc plugins.
4030
*/
41-
public fun protocPlugin(plugin: ProtocPlugin)
31+
public fun plugins(action: Action<NamedDomainObjectContainer<ProtocPlugin>>)
4232

4333
/**
4434
* Default [SourceDirectorySet] for proto files.

gradle-plugin/src/main/kotlin/kotlinx/rpc/protoc/ProtocExtension.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,18 @@ package kotlinx.rpc.protoc
66

77
import kotlinx.rpc.buf.BufExtension
88
import org.gradle.api.Action
9-
import org.gradle.api.NamedDomainObjectContainer
109

1110
/**
12-
* Configuration for the gRPC capabilities.
11+
* Configuration for the Protoc capabilities.
1312
*
14-
* To enable the gRPC capabilities, add the following minimal code to your `build.gradle.kts`:
13+
* To enable the Protoc capabilities, add the following minimal code to your `build.gradle.kts`:
1514
* ```kotlin
1615
* rpc {
1716
* protoc()
1817
* }
1918
* ```
2019
*/
2120
public interface ProtocExtension {
22-
/**
23-
* List of protoc plugins to be applied to the project.
24-
*/
25-
public val plugins: NamedDomainObjectContainer<ProtocPlugin>
26-
27-
/**
28-
* Configures the protoc plugins.
29-
*/
30-
public fun plugins(action: Action<NamedDomainObjectContainer<ProtocPlugin>>)
31-
3221
/**
3322
* Configuration for the Buf build tool.
3423
*/

gradle-plugin/src/main/kotlin/kotlinx/rpc/protoc/pluginJars.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ internal fun Project.configureGrpcKotlinMultiplatformPluginJarConfiguration() {
5252
)
5353
}
5454

55-
private fun Project.jarPathAccessor(name: String): Provider<String> =
56-
project.configurations.named(name)
57-
.map { it.singleFile.absolutePath }
55+
private fun Project.jarPathAccessor(name: String): Provider<String> = project.provider {
56+
configurations.named(name).get().singleFile.absolutePath
57+
}
5858

5959
private fun Project.configureJarConfiguration(configurationName: String, pluginArtifactName: String) {
6060
configurations.create(configurationName)

0 commit comments

Comments
 (0)