From 51ae8e916c98b580966b30f0f33dd70f9ef72379 Mon Sep 17 00:00:00 2001 From: John Chadwick Date: Mon, 8 Jul 2024 16:49:44 -0400 Subject: [PATCH] Add support for Editions --- .../proto/buf/editions/v1/editions.proto | 43 +++++++++++++++++++ .../connectrpc/protocgen/connect/Generator.kt | 15 +++++++ .../connect/internal/CodeGenerator.kt | 18 ++++++++ .../protocgen/connect/internal/Plugin.kt | 6 ++- 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto diff --git a/protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto b/protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto new file mode 100644 index 00000000..0bdd2da7 --- /dev/null +++ b/protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto @@ -0,0 +1,43 @@ +// Copyright 2022-2023 The Connect Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +edition = "2023"; + +package buf.editions.v1; + +option features.field_presence = IMPLICIT; + +message EditionsRequest { + message NestedMessage { + string not_utf8 = 1 [ features.utf8_validation = NONE ]; + } + + repeated NestedMessage nested = 1 [ + features.repeated_field_encoding = EXPANDED, + features.message_encoding = DELIMITED + ]; +} + +message EditionsResponse { + enum NestedEnum { + option features.enum_type = CLOSED; + NESTED_ENUM_VALUE_UNSPECIFIED = 0; + } + + NestedEnum enum = 1 [ features.field_presence = EXPLICIT ]; +} + +service EditionsService { + rpc Editions(EditionsRequest) returns (EditionsResponse) {} +} diff --git a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/Generator.kt b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/Generator.kt index 116aa90f..f7ede2f6 100644 --- a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/Generator.kt +++ b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/Generator.kt @@ -95,6 +95,21 @@ class Generator : CodeGenerator { } } + override fun getSupportedFeatures(): Array { + return arrayOf( + PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL, + PluginProtos.CodeGeneratorResponse.Feature.FEATURE_SUPPORTS_EDITIONS, + ) + } + + override fun getMinimumEdition(): DescriptorProtos.Edition { + return DescriptorProtos.Edition.EDITION_PROTO2 + } + + override fun getMaximumEdition(): DescriptorProtos.Edition { + return DescriptorProtos.Edition.EDITION_2023 + } + private fun parseFile(file: Descriptors.FileDescriptor): Map { val baseSourceInfo = SourceInfo(protoFileMap[file.name]!!, descriptorSource, emptyList()) val fileSpecs = mutableMapOf() diff --git a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/CodeGenerator.kt b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/CodeGenerator.kt index 3bc0206c..0a359018 100644 --- a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/CodeGenerator.kt +++ b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/CodeGenerator.kt @@ -15,6 +15,7 @@ package com.connectrpc.protocgen.connect.internal import com.connectrpc.protocgen.connect.internal.Plugin.DescriptorSource +import com.google.protobuf.DescriptorProtos.Edition import com.google.protobuf.compiler.PluginProtos /** @@ -30,4 +31,21 @@ interface CodeGenerator { descriptorSource: DescriptorSource, response: Plugin.Response, ) + + /** + * Returns an array of supported Protobuf features. + */ + fun getSupportedFeatures(): Array + + /** + * Returns the minimum edition (inclusive) supported by this generator. Any + * proto files with an edition before this will result in an error. + */ + fun getMinimumEdition(): Edition + + /** + * Returns the maximum edition (inclusive) supported by this generator. Any + * proto files with an edition after this will result in an error. + */ + fun getMaximumEdition(): Edition } diff --git a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/Plugin.kt b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/Plugin.kt index 0e9a0e95..f483082d 100644 --- a/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/Plugin.kt +++ b/protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/internal/Plugin.kt @@ -109,10 +109,12 @@ object Plugin { try { // go ahead and write response preamble PluginProtos.CodeGeneratorResponse - .newBuilder() // add more here as more features are introduced and then supported + .newBuilder() .setSupportedFeatures( - toFeatureBitmask(PluginProtos.CodeGeneratorResponse.Feature.FEATURE_PROTO3_OPTIONAL), + toFeatureBitmask(*generator.getSupportedFeatures()), ) + .setMinimumEdition(generator.getMinimumEdition().number) + .setMaximumEdition(generator.getMaximumEdition().number) .build() .writeTo(output) } catch (e: IOException) {