@@ -17,6 +17,8 @@ import Foundation
17
17
/// A protocol that generator should conform to then get easy support for
18
18
/// being a protocol buffer compiler pluign.
19
19
public protocol CodeGenerator {
20
+ init ( )
21
+
20
22
/// Generates code for the given proto files.
21
23
///
22
24
/// - Parameters:
@@ -42,6 +44,107 @@ public protocol CodeGenerator {
42
44
/// The list of features this CodeGenerator support to be reported back to
43
45
/// the protocol buffer compiler.
44
46
var supportedFeatures : [ Google_Protobuf_Compiler_CodeGeneratorResponse . Feature ] { get }
47
+
48
+ /// If provided, the argument parsing will support `--version` and report
49
+ /// this value.
50
+ var version : String ? { get }
51
+
52
+ /// If provided and `printHelp` isn't provide, this value will be including in
53
+ /// default output for the `--help` output.
54
+ var projectURL : String ? { get }
55
+
56
+ /// If provided and `printHelp` isn't provide, this value will be including in
57
+ /// default output for the `--help` output.
58
+ var copyrightLine : String ? { get }
59
+
60
+ /// Will be called for `-h` or `--help`, should `print()` out whatever is
61
+ /// desired; there is a default implementation that uses the above info
62
+ /// when provided.
63
+ func printHelp( )
64
+ }
65
+
66
+ extension CodeGenerator {
67
+ var programName : String {
68
+ guard let name = CommandLine . arguments. first? . split ( separator: " / " ) . last else {
69
+ return " <plugin> "
70
+ }
71
+ return String ( name)
72
+ }
73
+
74
+ /// Runs as a protocol buffer compiler plugin based on the given arguments
75
+ /// or falls back to `CommandLine.arguments`.
76
+ public func main( _ args: [ String ] ? ) {
77
+ let args = args ?? Array ( CommandLine . arguments. dropFirst ( ) )
78
+
79
+ for arg in args {
80
+ if arg == " --version " , let version = version {
81
+ print ( " \( programName) \( version) " )
82
+ return
83
+ }
84
+ if arg == " -h " || arg == " --help " {
85
+ printHelp ( )
86
+ return
87
+ }
88
+ // Could look at bringing back the support for recorded requests, but
89
+ // haven't needed it in a long time.
90
+ var stderr = StandardErrorOutputStream ( )
91
+ print ( " Unknown argument: \( arg) " , to: & stderr)
92
+ return
93
+ }
94
+
95
+ let response : Google_Protobuf_Compiler_CodeGeneratorResponse
96
+ do {
97
+ let request = try Google_Protobuf_Compiler_CodeGeneratorRequest (
98
+ serializedData: FileHandle . standardInput. readDataToEndOfFile ( ) )
99
+ response = generateCode ( request: request, generator: self )
100
+ } catch let e {
101
+ response = Google_Protobuf_Compiler_CodeGeneratorResponse (
102
+ error: " Received an unparsable request from the compiler: \( e) " )
103
+ }
104
+
105
+ let serializedResponse : Data
106
+ do {
107
+ serializedResponse = try response. serializedBytes ( )
108
+ } catch let e {
109
+ var stderr = StandardErrorOutputStream ( )
110
+ print ( " \( programName) : Failure while serializing response: \( e) " , to: & stderr)
111
+ return
112
+ }
113
+ FileHandle . standardOutput. write ( serializedResponse)
114
+ }
115
+
116
+ /// Runs as a protocol buffer compiler plugin; reading the generation request
117
+ /// off stdin and sending the response on stdout.
118
+ ///
119
+ /// Instead of calling this, just add `@main` to your `CodeGenerator`.
120
+ public static func main( ) {
121
+ let generator = Self ( )
122
+ generator. main ( nil )
123
+ }
124
+ }
125
+
126
+ // Provide default implementation for things so `CodeGenerator`s only have to
127
+ // provide them if they wish too.
128
+ extension CodeGenerator {
129
+ public var version : String ? { return nil }
130
+ public var projectURL : String ? { return nil }
131
+ public var copyrightLine : String ? { return nil }
132
+
133
+ public func printHelp( ) {
134
+ print ( " \( programName) : A plugin for protoc and should not normally be run directly. " )
135
+ if let copyright = copyrightLine {
136
+ print ( " \( copyright) " )
137
+ }
138
+ if let projectURL = projectURL {
139
+ print (
140
+ """
141
+
142
+ For more information on the usage of this plugin, please see:
143
+ \( projectURL)
144
+
145
+ """ )
146
+ }
147
+ }
45
148
}
46
149
47
150
/// Uses the given `Google_Protobuf_Compiler_CodeGeneratorRequest` and
0 commit comments