Skip to content

Commit

Permalink
Add support for Editions (#297)
Browse files Browse the repository at this point in the history
As expected, there aren't any (noticeable) issues with enabling editions
in Connect Kotlin. I did take this opportunity to make the
`CodeGenerator` interface match closer to the upstream protobuf
`CodeGenerator` interface (at least from the C++ version) so that
information about editions and features support would be conveyed by the
`CodeGenerator` rather than being hardcoded in the `Plugin` code.

Signed-off-by: John Chadwick <[email protected]>
  • Loading branch information
jchadwick-buf authored Jul 9, 2024
1 parent 234a590 commit dc7d1cf
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 2 deletions.
43 changes: 43 additions & 0 deletions protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto
Original file line number Diff line number Diff line change
@@ -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) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ class Generator : CodeGenerator {
}
}

override fun getSupportedFeatures(): Array<PluginProtos.CodeGeneratorResponse.Feature> {
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<ClassName, FileSpec> {
val baseSourceInfo = SourceInfo(protoFileMap[file.name]!!, descriptorSource, emptyList())
val fileSpecs = mutableMapOf<ClassName, FileSpec>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand All @@ -30,4 +31,21 @@ interface CodeGenerator {
descriptorSource: DescriptorSource,
response: Plugin.Response,
)

/**
* Returns an array of supported Protobuf features.
*/
fun getSupportedFeatures(): Array<PluginProtos.CodeGeneratorResponse.Feature>

/**
* 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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit dc7d1cf

Please sign in to comment.