From 84138e3a6691db6abd7d5856906612ad42d503ec Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Thu, 28 Mar 2024 00:33:58 -0700 Subject: [PATCH 01/11] add reflection option to plugin configuration --- Plugins/GRPCSwiftPlugin/plugin.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Plugins/GRPCSwiftPlugin/plugin.swift b/Plugins/GRPCSwiftPlugin/plugin.swift index f29000bc0..37c525829 100644 --- a/Plugins/GRPCSwiftPlugin/plugin.swift +++ b/Plugins/GRPCSwiftPlugin/plugin.swift @@ -65,6 +65,8 @@ struct GRPCSwiftPlugin { var server: Bool? /// Whether client code is generated. var client: Bool? + /// Whether reflection data is generated. + var reflection: Bool? /// Determines whether the casing of generated function names is kept. var keepMethodCasing: Bool? } @@ -186,6 +188,10 @@ struct GRPCSwiftPlugin { protocArgs.append("--grpc-swift_opt=Client=\(generateClientCode)") } + if let generateReflectionData = invocation.reflection { + protocArgs.append("--grpc-swift_opt=ReflectionData=\(generateReflectionData)") + } + if let keepMethodCasingOption = invocation.keepMethodCasing { protocArgs.append("--grpc-swift_opt=KeepMethodCasing=\(keepMethodCasingOption)") } From 16501f5c6cd5b8fc83e1650440f2bd3f074805c6 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Thu, 28 Mar 2024 00:35:15 -0700 Subject: [PATCH 02/11] if reflection is enabled, include reflection file as an output file --- Plugins/GRPCSwiftPlugin/plugin.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Plugins/GRPCSwiftPlugin/plugin.swift b/Plugins/GRPCSwiftPlugin/plugin.swift index 37c525829..a9623e311 100644 --- a/Plugins/GRPCSwiftPlugin/plugin.swift +++ b/Plugins/GRPCSwiftPlugin/plugin.swift @@ -213,6 +213,12 @@ struct GRPCSwiftPlugin { // Add the outputPath as an output file outputFiles.append(protobufOutputPath) + + if invocation.reflection == true { + let reflectionFile = file.replacingOccurrences(of: "grpc.swift", with: "grpc.reflection") + let reflectionOutputPath = outputDirectory.appending(reflectionFile) + outputFiles.append(reflectionOutputPath) + } } // Construct the command. Specifying the input and output paths lets the build From 2438e9267b44cbd4bd44952e54b0f273783a1951 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Thu, 28 Mar 2024 00:36:23 -0700 Subject: [PATCH 03/11] include example server using plugin and reflection --- Package.swift | 15 ++++++ Sources/Examples/Plugin/GreeterProvider.swift | 29 +++++++++++ Sources/Examples/Plugin/PluginServer.swift | 50 +++++++++++++++++++ .../Plugin/SecretGreeterProvider.swift | 29 +++++++++++ Sources/Examples/Plugin/greeter.proto | 15 ++++++ .../Examples/Plugin/grpc-swift-config.json | 20 ++++++++ Sources/Examples/Plugin/secret.proto | 15 ++++++ .../Plugin/swift-protobuf-config.json | 16 ++++++ 8 files changed, 189 insertions(+) create mode 100644 Sources/Examples/Plugin/GreeterProvider.swift create mode 100644 Sources/Examples/Plugin/PluginServer.swift create mode 100644 Sources/Examples/Plugin/SecretGreeterProvider.swift create mode 100644 Sources/Examples/Plugin/greeter.proto create mode 100644 Sources/Examples/Plugin/grpc-swift-config.json create mode 100644 Sources/Examples/Plugin/secret.proto create mode 100644 Sources/Examples/Plugin/swift-protobuf-config.json diff --git a/Package.swift b/Package.swift index 699ff4baa..4a28bf1d4 100644 --- a/Package.swift +++ b/Package.swift @@ -604,6 +604,20 @@ extension Target { path: "Sources/GRPCReflectionService" ) + static let pluginServer: Target = .executableTarget( + name: "PluginServer", + dependencies: [ + .grpc, + .reflectionService, + .nioPosix, + .argumentParser + ], + path: "Sources/Examples/Plugin", + plugins: [ + .plugin(name: "SwiftProtobufPlugin", package: "swift-protobuf"), + .plugin(name: "GRPCSwiftPlugin"), + ]) + static let reflectionServer: Target = .executableTarget( name: "ReflectionServer", dependencies: [ @@ -722,6 +736,7 @@ let package = Package( .routeGuideServer, .packetCapture, .reflectionServer, + .pluginServer, // v2 .grpcCore, diff --git a/Sources/Examples/Plugin/GreeterProvider.swift b/Sources/Examples/Plugin/GreeterProvider.swift new file mode 100644 index 000000000..0934ca856 --- /dev/null +++ b/Sources/Examples/Plugin/GreeterProvider.swift @@ -0,0 +1,29 @@ +/* + * Copyright 2019, gRPC Authors All rights reserved. + * + * 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. + */ + +import GRPC + +@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +final class GreeterProvider: Examples_GreeterAsyncProvider { + func greet( + request: Examples_GreeterRequest, + context _: GRPC.GRPCAsyncServerCallContext + ) async throws -> Examples_GreeterReply { + return Examples_GreeterReply.with { + $0.message = "Hello \(request.name)" + } + } +} diff --git a/Sources/Examples/Plugin/PluginServer.swift b/Sources/Examples/Plugin/PluginServer.swift new file mode 100644 index 000000000..c85f06e3c --- /dev/null +++ b/Sources/Examples/Plugin/PluginServer.swift @@ -0,0 +1,50 @@ +/* + * Copyright 2019, gRPC Authors All rights reserved. + * + * 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. + */ + +import ArgumentParser +import Foundation +import GRPC +import GRPCReflectionService +import NIOPosix + +@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +@main +struct ReflectionServer: AsyncParsableCommand { + func run() async throws { + let reflectionDataFilePaths = Bundle.module.paths( + forResourcesOfType: "reflection", + inDirectory: nil + ) + let reflectionService = try ReflectionService( + reflectionDataFilePaths: reflectionDataFilePaths, + version: .v1Alpha + ) + + // Start the server and print its address once it has started. + let server = try await Server.insecure(group: MultiThreadedEventLoopGroup.singleton) + .withServiceProviders([ + GreeterProvider(), + SecretGreeterProvider(), + reflectionService, + ]) + .bind(host: "localhost", port: 1234) + .get() + + print("server started on port \(server.channel.localAddress!.port!)") + // Wait on the server's `onClose` future to stop the program from exiting. + try await server.onClose.get() + } +} diff --git a/Sources/Examples/Plugin/SecretGreeterProvider.swift b/Sources/Examples/Plugin/SecretGreeterProvider.swift new file mode 100644 index 000000000..c367c82f6 --- /dev/null +++ b/Sources/Examples/Plugin/SecretGreeterProvider.swift @@ -0,0 +1,29 @@ +/* + * Copyright 2019, gRPC Authors All rights reserved. + * + * 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. + */ + +import GRPC + +@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) +final class SecretGreeterProvider: Examples_SecretGreeterAsyncProvider { + func greet( + request: Examples_SecretGreeterRequest, + context: GRPCAsyncServerCallContext + ) async throws -> Examples_SecretGreeterReply { + return Examples_SecretGreeterReply.with { + $0.message = "Hello agent \(request.name)" + } + } +} diff --git a/Sources/Examples/Plugin/greeter.proto b/Sources/Examples/Plugin/greeter.proto new file mode 100644 index 000000000..1c9f7974e --- /dev/null +++ b/Sources/Examples/Plugin/greeter.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package examples; + +service Greeter { + rpc Greet(GreeterRequest) returns (GreeterReply); +} + +message GreeterRequest { + string name = 1; +} + +message GreeterReply { + string message = 1; +} diff --git a/Sources/Examples/Plugin/grpc-swift-config.json b/Sources/Examples/Plugin/grpc-swift-config.json new file mode 100644 index 000000000..171aae4ed --- /dev/null +++ b/Sources/Examples/Plugin/grpc-swift-config.json @@ -0,0 +1,20 @@ +{ + "invocations": [ + { + "protoFiles": [ + "greeter.proto" + ], + "visibility": "public", + "server": true, + "reflection": true + }, + { + "protoFiles": [ + "secret.proto" + ], + "visibility": "public", + "server": true, + "reflection": false + } + ] +} diff --git a/Sources/Examples/Plugin/secret.proto b/Sources/Examples/Plugin/secret.proto new file mode 100644 index 000000000..107bcc5b5 --- /dev/null +++ b/Sources/Examples/Plugin/secret.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package examples; + +service SecretGreeter { + rpc Greet(SecretGreeterRequest) returns (SecretGreeterReply); +} + +message SecretGreeterRequest { + string name = 1; +} + +message SecretGreeterReply { + string message = 1; +} diff --git a/Sources/Examples/Plugin/swift-protobuf-config.json b/Sources/Examples/Plugin/swift-protobuf-config.json new file mode 100644 index 000000000..6198ae8a2 --- /dev/null +++ b/Sources/Examples/Plugin/swift-protobuf-config.json @@ -0,0 +1,16 @@ +{ + "invocations": [ + { + "protoFiles": [ + "greeter.proto" + ], + "visibility": "public" + }, + { + "protoFiles": [ + "secret.proto" + ], + "visibility": "public" + } + ] +} From a5b6fc29ff3b5388922f966328b3ab17dc222e1b Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Thu, 28 Mar 2024 00:36:36 -0700 Subject: [PATCH 04/11] add protoc to github actions --- .github/workflows/ci.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 84076c692..c3d231151 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,6 +38,8 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: 🔧 Build run: swift build ${{ matrix.swift-build-flags }} timeout-minutes: 20 @@ -99,6 +101,8 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: 🧮 Allocation Counting Tests run: ./Performance/allocations/test-allocation-counts.sh env: ${{ matrix.env }} @@ -125,6 +129,8 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 + - name: Install Protoc + uses: arduino/setup-protoc@v3 - name: Build without NIOSSL run: swift build env: From 33b08848ebfbebf0f5c20dcf84b7fb33f59a3667 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Thu, 28 Mar 2024 01:20:11 -0700 Subject: [PATCH 05/11] install protoc via apt --- .github/workflows/ci.yaml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c3d231151..a1944a6e8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,8 +38,8 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - - name: Install Protoc - uses: arduino/setup-protoc@v3 + - name: Install protoc + run: apt update && apt install protobuf-compiler -y - name: 🔧 Build run: swift build ${{ matrix.swift-build-flags }} timeout-minutes: 20 @@ -101,8 +101,6 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - - name: Install Protoc - uses: arduino/setup-protoc@v3 - name: 🧮 Allocation Counting Tests run: ./Performance/allocations/test-allocation-counts.sh env: ${{ matrix.env }} @@ -129,8 +127,8 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - - name: Install Protoc - uses: arduino/setup-protoc@v3 + - name: Install protoc + run: apt update && apt install protobuf-compiler -y - name: Build without NIOSSL run: swift build env: From 75f3ee86437ce25231c6eccf78b298970c07b262 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Tue, 2 Apr 2024 10:01:14 -0700 Subject: [PATCH 06/11] remove plugin example --- .github/workflows/ci.yaml | 4 -- Sources/Examples/Plugin/GreeterProvider.swift | 29 ----------- Sources/Examples/Plugin/PluginServer.swift | 50 ------------------- .../Plugin/SecretGreeterProvider.swift | 29 ----------- Sources/Examples/Plugin/greeter.proto | 15 ------ .../Examples/Plugin/grpc-swift-config.json | 20 -------- Sources/Examples/Plugin/secret.proto | 15 ------ .../Plugin/swift-protobuf-config.json | 16 ------ 8 files changed, 178 deletions(-) delete mode 100644 Sources/Examples/Plugin/GreeterProvider.swift delete mode 100644 Sources/Examples/Plugin/PluginServer.swift delete mode 100644 Sources/Examples/Plugin/SecretGreeterProvider.swift delete mode 100644 Sources/Examples/Plugin/greeter.proto delete mode 100644 Sources/Examples/Plugin/grpc-swift-config.json delete mode 100644 Sources/Examples/Plugin/secret.proto delete mode 100644 Sources/Examples/Plugin/swift-protobuf-config.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a1944a6e8..84076c692 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -38,8 +38,6 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - - name: Install protoc - run: apt update && apt install protobuf-compiler -y - name: 🔧 Build run: swift build ${{ matrix.swift-build-flags }} timeout-minutes: 20 @@ -127,8 +125,6 @@ jobs: image: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - - name: Install protoc - run: apt update && apt install protobuf-compiler -y - name: Build without NIOSSL run: swift build env: diff --git a/Sources/Examples/Plugin/GreeterProvider.swift b/Sources/Examples/Plugin/GreeterProvider.swift deleted file mode 100644 index 0934ca856..000000000 --- a/Sources/Examples/Plugin/GreeterProvider.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019, gRPC Authors All rights reserved. - * - * 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. - */ - -import GRPC - -@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) -final class GreeterProvider: Examples_GreeterAsyncProvider { - func greet( - request: Examples_GreeterRequest, - context _: GRPC.GRPCAsyncServerCallContext - ) async throws -> Examples_GreeterReply { - return Examples_GreeterReply.with { - $0.message = "Hello \(request.name)" - } - } -} diff --git a/Sources/Examples/Plugin/PluginServer.swift b/Sources/Examples/Plugin/PluginServer.swift deleted file mode 100644 index c85f06e3c..000000000 --- a/Sources/Examples/Plugin/PluginServer.swift +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2019, gRPC Authors All rights reserved. - * - * 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. - */ - -import ArgumentParser -import Foundation -import GRPC -import GRPCReflectionService -import NIOPosix - -@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) -@main -struct ReflectionServer: AsyncParsableCommand { - func run() async throws { - let reflectionDataFilePaths = Bundle.module.paths( - forResourcesOfType: "reflection", - inDirectory: nil - ) - let reflectionService = try ReflectionService( - reflectionDataFilePaths: reflectionDataFilePaths, - version: .v1Alpha - ) - - // Start the server and print its address once it has started. - let server = try await Server.insecure(group: MultiThreadedEventLoopGroup.singleton) - .withServiceProviders([ - GreeterProvider(), - SecretGreeterProvider(), - reflectionService, - ]) - .bind(host: "localhost", port: 1234) - .get() - - print("server started on port \(server.channel.localAddress!.port!)") - // Wait on the server's `onClose` future to stop the program from exiting. - try await server.onClose.get() - } -} diff --git a/Sources/Examples/Plugin/SecretGreeterProvider.swift b/Sources/Examples/Plugin/SecretGreeterProvider.swift deleted file mode 100644 index c367c82f6..000000000 --- a/Sources/Examples/Plugin/SecretGreeterProvider.swift +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019, gRPC Authors All rights reserved. - * - * 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. - */ - -import GRPC - -@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) -final class SecretGreeterProvider: Examples_SecretGreeterAsyncProvider { - func greet( - request: Examples_SecretGreeterRequest, - context: GRPCAsyncServerCallContext - ) async throws -> Examples_SecretGreeterReply { - return Examples_SecretGreeterReply.with { - $0.message = "Hello agent \(request.name)" - } - } -} diff --git a/Sources/Examples/Plugin/greeter.proto b/Sources/Examples/Plugin/greeter.proto deleted file mode 100644 index 1c9f7974e..000000000 --- a/Sources/Examples/Plugin/greeter.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package examples; - -service Greeter { - rpc Greet(GreeterRequest) returns (GreeterReply); -} - -message GreeterRequest { - string name = 1; -} - -message GreeterReply { - string message = 1; -} diff --git a/Sources/Examples/Plugin/grpc-swift-config.json b/Sources/Examples/Plugin/grpc-swift-config.json deleted file mode 100644 index 171aae4ed..000000000 --- a/Sources/Examples/Plugin/grpc-swift-config.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "invocations": [ - { - "protoFiles": [ - "greeter.proto" - ], - "visibility": "public", - "server": true, - "reflection": true - }, - { - "protoFiles": [ - "secret.proto" - ], - "visibility": "public", - "server": true, - "reflection": false - } - ] -} diff --git a/Sources/Examples/Plugin/secret.proto b/Sources/Examples/Plugin/secret.proto deleted file mode 100644 index 107bcc5b5..000000000 --- a/Sources/Examples/Plugin/secret.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto3"; - -package examples; - -service SecretGreeter { - rpc Greet(SecretGreeterRequest) returns (SecretGreeterReply); -} - -message SecretGreeterRequest { - string name = 1; -} - -message SecretGreeterReply { - string message = 1; -} diff --git a/Sources/Examples/Plugin/swift-protobuf-config.json b/Sources/Examples/Plugin/swift-protobuf-config.json deleted file mode 100644 index 6198ae8a2..000000000 --- a/Sources/Examples/Plugin/swift-protobuf-config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "invocations": [ - { - "protoFiles": [ - "greeter.proto" - ], - "visibility": "public" - }, - { - "protoFiles": [ - "secret.proto" - ], - "visibility": "public" - } - ] -} From 1fe50d6d40d0b7de7a2224ac93deb4abde1d79f5 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Tue, 2 Apr 2024 10:01:24 -0700 Subject: [PATCH 07/11] update package.swift --- Package.swift | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Package.swift b/Package.swift index 4a28bf1d4..699ff4baa 100644 --- a/Package.swift +++ b/Package.swift @@ -604,20 +604,6 @@ extension Target { path: "Sources/GRPCReflectionService" ) - static let pluginServer: Target = .executableTarget( - name: "PluginServer", - dependencies: [ - .grpc, - .reflectionService, - .nioPosix, - .argumentParser - ], - path: "Sources/Examples/Plugin", - plugins: [ - .plugin(name: "SwiftProtobufPlugin", package: "swift-protobuf"), - .plugin(name: "GRPCSwiftPlugin"), - ]) - static let reflectionServer: Target = .executableTarget( name: "ReflectionServer", dependencies: [ @@ -736,7 +722,6 @@ let package = Package( .routeGuideServer, .packetCapture, .reflectionServer, - .pluginServer, // v2 .grpcCore, From 95557bc74217c75ad6835f2dbe1f1925fa67d70c Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Tue, 2 Apr 2024 10:01:44 -0700 Subject: [PATCH 08/11] change name to reflectionData --- Plugins/GRPCSwiftPlugin/plugin.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/GRPCSwiftPlugin/plugin.swift b/Plugins/GRPCSwiftPlugin/plugin.swift index a9623e311..92f33a6a7 100644 --- a/Plugins/GRPCSwiftPlugin/plugin.swift +++ b/Plugins/GRPCSwiftPlugin/plugin.swift @@ -66,7 +66,7 @@ struct GRPCSwiftPlugin { /// Whether client code is generated. var client: Bool? /// Whether reflection data is generated. - var reflection: Bool? + var reflectionData: Bool? /// Determines whether the casing of generated function names is kept. var keepMethodCasing: Bool? } @@ -188,7 +188,7 @@ struct GRPCSwiftPlugin { protocArgs.append("--grpc-swift_opt=Client=\(generateClientCode)") } - if let generateReflectionData = invocation.reflection { + if let generateReflectionData = invocation.reflectionData { protocArgs.append("--grpc-swift_opt=ReflectionData=\(generateReflectionData)") } From 20d5790456bcb413016c1fa4aca527ec48e84c22 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Tue, 2 Apr 2024 10:02:00 -0700 Subject: [PATCH 09/11] change how file names are calculated --- Plugins/GRPCSwiftPlugin/plugin.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Plugins/GRPCSwiftPlugin/plugin.swift b/Plugins/GRPCSwiftPlugin/plugin.swift index 92f33a6a7..bd0ee045b 100644 --- a/Plugins/GRPCSwiftPlugin/plugin.swift +++ b/Plugins/GRPCSwiftPlugin/plugin.swift @@ -214,11 +214,13 @@ struct GRPCSwiftPlugin { // Add the outputPath as an output file outputFiles.append(protobufOutputPath) - if invocation.reflection == true { - let reflectionFile = file.replacingOccurrences(of: "grpc.swift", with: "grpc.reflection") - let reflectionOutputPath = outputDirectory.appending(reflectionFile) - outputFiles.append(reflectionOutputPath) - } + if invocation.reflectionData == true { + // Remove .swift extension and add .reflection extension + file.removeLast(5) + file.append("reflection") + let reflectionOutputPath = outputDirectory.appending(file) + outputFiles.append(reflectionOutputPath) + } } // Construct the command. Specifying the input and output paths lets the build From f675bad1be3721db16c5d501b73532cfda6d9de1 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Tue, 2 Apr 2024 10:02:07 -0700 Subject: [PATCH 10/11] update docs --- .../ReflectionServiceTutorial.md | 20 +++++++++++++++++++ .../Docs.docc/spm-plugin.md | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md index 68db44286..6df9c04af 100644 --- a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md +++ b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md @@ -70,6 +70,25 @@ You can use Swift Package Manager [resources][swiftpm-resources] to add the gene In our example the reflection data is written into the "Generated" directory within the target so we include the `.copy("Generated")` rule in our target's resource list. +#### SPM Plugin + +Reflection data can also be generated via the SPM plugin by including `"reflectionData": true` in `grpc-swift-config.json`. This will generate the same data as running `protoc` above. The generated data will be in your `.build` folder (or `DerivedData` if running from Xcode) and included in the build process. More about [spm-plugin][spm-plugin] can be found here. + +```json +{ + "invocations": [ + { + "protoFiles": [ + "helloworld.proto" + ], + "visibility": "public", + "server": true, + "reflectionData": true + } + ] +} +``` + ### Instantiating the Reflection service To instantiate the `ReflectionService` you need to pass the URLs of the files containing @@ -192,3 +211,4 @@ Note that when specifying a service, a method or a symbol, we have to use the fu [echo-proto]: ../../Examples/Echo/Model/echo.proto [grpcurl-v188]: https://github.com/fullstorydev/grpcurl/releases/tag/v1.8.8 [swiftpm-resources]: https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageDescription.md#resource +[spm-plugin]: ../../protoc-gen-grpc-swift/Docs.docc/spm-plugin.md \ No newline at end of file diff --git a/Sources/protoc-gen-grpc-swift/Docs.docc/spm-plugin.md b/Sources/protoc-gen-grpc-swift/Docs.docc/spm-plugin.md index 807b766fe..61a2e10f0 100644 --- a/Sources/protoc-gen-grpc-swift/Docs.docc/spm-plugin.md +++ b/Sources/protoc-gen-grpc-swift/Docs.docc/spm-plugin.md @@ -81,7 +81,8 @@ Sources ], "visibility": "public", "client": false, - "keepMethodCasing": false + "keepMethodCasing": false, + "reflectionData": true } ] } From cf107a99d05598db0d6f91f646d751db05fb3e45 Mon Sep 17 00:00:00 2001 From: Sami Suteria Date: Wed, 3 Apr 2024 09:47:49 -0700 Subject: [PATCH 11/11] update docs --- .../ReflectionServiceTutorial.md | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md index 6df9c04af..0ad6941bf 100644 --- a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md +++ b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md @@ -70,25 +70,6 @@ You can use Swift Package Manager [resources][swiftpm-resources] to add the gene In our example the reflection data is written into the "Generated" directory within the target so we include the `.copy("Generated")` rule in our target's resource list. -#### SPM Plugin - -Reflection data can also be generated via the SPM plugin by including `"reflectionData": true` in `grpc-swift-config.json`. This will generate the same data as running `protoc` above. The generated data will be in your `.build` folder (or `DerivedData` if running from Xcode) and included in the build process. More about [spm-plugin][spm-plugin] can be found here. - -```json -{ - "invocations": [ - { - "protoFiles": [ - "helloworld.proto" - ], - "visibility": "public", - "server": true, - "reflectionData": true - } - ] -} -``` - ### Instantiating the Reflection service To instantiate the `ReflectionService` you need to pass the URLs of the files containing @@ -121,6 +102,38 @@ let reflectionService = try ReflectionService( ) ``` +### Swift Package Manager Plugin + +Reflection data can also be generated via the SPM plugin by including `"reflectionData": true` in `grpc-swift-config.json`. This will generate the same reflection data as running `protoc` above. The generated reflection files are added to your module Bundle and can be accessed at runtime. More about [spm-plugin][spm-plugin] can be found here. + +```json +{ + "invocations": [ + { + "protoFiles": [ + "helloworld.proto" + ], + "visibility": "public", + "server": true, + "reflectionData": true + } + ] +} +``` + +To instantiate the `ReflectionService` you can search for files with the extension `reflection` in your module Bundle. + +```swift +let reflectionDataFilePaths = Bundle.module.paths( + forResourcesOfType: "reflection", + inDirectory: nil +) +let reflectionService = try ReflectionService( + reflectionDataFilePaths: reflectionDataFilePaths, + version: .v1Alpha +) +``` + ### Running the server In our example the server isn't configured with TLS and listens on localhost port 1234.