diff --git a/Plugins/GRPCSwiftPlugin/plugin.swift b/Plugins/GRPCSwiftPlugin/plugin.swift index f29000bc0..bd0ee045b 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 reflectionData: 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.reflectionData { + protocArgs.append("--grpc-swift_opt=ReflectionData=\(generateReflectionData)") + } + if let keepMethodCasingOption = invocation.keepMethodCasing { protocArgs.append("--grpc-swift_opt=KeepMethodCasing=\(keepMethodCasingOption)") } @@ -207,6 +213,14 @@ struct GRPCSwiftPlugin { // Add the outputPath as an output file outputFiles.append(protobufOutputPath) + + 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 diff --git a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md index 68db44286..0ad6941bf 100644 --- a/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md +++ b/Sources/GRPCReflectionService/Documentation.docc/ReflectionServiceTutorial.md @@ -102,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. @@ -192,3 +224,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 } ] }