Browse Source

Basic scaffolding for a code generation plugin.

Tim Burks 9 years ago
parent
commit
7db97e09ba
3 changed files with 173 additions and 0 deletions
  1. 22 0
      Plugin/Package.swift
  2. 100 0
      Plugin/Sources/io.swift
  3. 51 0
      Plugin/Sources/main.swift

+ 22 - 0
Plugin/Package.swift

@@ -0,0 +1,22 @@
+// Copyright 2016 Google Inc. 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 PackageDescription
+
+let package = Package(
+    name: "protoc-gen-swiftgrpc",
+    dependencies: [
+        .Package(url: "https://github.com/apple/swift-protobuf.git", Version(0,9,24))
+    ]
+)

+ 100 - 0
Plugin/Sources/io.swift

@@ -0,0 +1,100 @@
+// Copyright 2016 Google Inc. 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 Foundation
+
+// The I/O code below is derived from Apple's swift-protobuf project.
+// https://github.com/apple/swift-protobuf
+// BEGIN swift-protobuf derivation
+
+#if os(Linux)
+  import Glibc
+#else
+  import Darwin.C
+#endif
+
+enum PluginError: Error {
+  /// Raised for any errors reading the input
+  case readFailure
+}
+
+// Alias clib's write() so Stdout.write(bytes:) can call it.
+private let _write = write
+
+class Stdin {
+  static func readall() throws -> Data {
+    let fd: Int32 = 0
+    let buffSize = 32
+    var buff = [UInt8]()
+    while true {
+      var fragment = [UInt8](repeating: 0, count: buffSize)
+      let count = read(fd, &fragment, buffSize)
+      if count < 0 {
+        throw PluginError.readFailure
+      }
+      if count < buffSize {
+        buff += fragment[0..<count]
+        return Data(bytes: buff)
+      }
+      buff += fragment
+    }
+  }
+}
+
+class Stdout {
+  static func write(bytes: Data) {
+    bytes.withUnsafeBytes { (p: UnsafePointer<UInt8>) -> () in
+      _ = _write(1, p, bytes.count)
+    }
+  }
+}
+
+struct CodePrinter {
+  private(set) var content = ""
+  private var currentIndentDepth = 0
+  private var currentIndent = ""
+  private var atLineStart = true
+
+  mutating func print(_ text: String...) {
+    for t in text {
+      for c in t.characters {
+        if c == "\n" {
+          content.append(c)
+          atLineStart = true
+        } else {
+          if atLineStart {
+            content.append(currentIndent)
+            atLineStart = false
+          }
+          content.append(c)
+        }
+      }
+    }
+  }
+
+  mutating private func resetIndent() {
+    currentIndent = (0..<currentIndentDepth).map { Int -> String in return "  " } .joined(separator:"")
+  }
+
+  mutating func indent() {
+    currentIndentDepth += 1
+    resetIndent()
+  }
+  mutating func outdent() {
+    currentIndentDepth -= 1
+    resetIndent()
+  }
+}
+
+// END swift-protobuf derivation

+ 51 - 0
Plugin/Sources/main.swift

@@ -0,0 +1,51 @@
+// Copyright 2016 Google Inc. 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 Foundation
+import SwiftProtobuf
+import PluginLibrary
+
+func main() throws {
+  var response = Google_Protobuf_Compiler_CodeGeneratorResponse()
+
+  var log = ""
+
+  let rawRequest = try Stdin.readall()
+  let request = try Google_Protobuf_Compiler_CodeGeneratorRequest(protobuf: rawRequest)
+
+  for protoFile in request.protoFile {
+    log += "File \(protoFile.name!)\n"
+    for service in protoFile.service {
+      log += "Service \(service.name!)\n"
+      for method in service.method {
+        log += " Method \(method.name!)\n"
+        log += "  input \(method.inputType!)\n"
+        log += "  output \(method.outputType!)\n"
+        log += "  client_streaming \(method.clientStreaming!)\n"
+        log += "  server_streaming \(method.serverStreaming!)\n"
+      }
+      log += " Options \(service.options)\n"
+    }
+  }
+  
+  var logfile = Google_Protobuf_Compiler_CodeGeneratorResponse.File()
+  logfile.name = "swiftgrpc.log"
+  logfile.content = log
+  response.file.append(logfile)
+
+  let serializedResponse = try response.serializeProtobuf()
+  Stdout.write(bytes: serializedResponse)
+}
+
+try main()