protoc-gen-twirp_ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../google/protobuf/compiler/plugin_pb"
4
+ require_relative "code_generator"
5
+
6
+ module Twirp
7
+ module ProtocPlugin
8
+ class Error < StandardError; end
9
+
10
+ class << self
11
+ # @param input [String] an encoded [Google::Protobuf::Compiler::CodeGeneratorRequest] message
12
+ # @return [String] an encoded [Google::Protobuf::Compiler::CodeGeneratorResponse] message
13
+ # @raise [Twirp::ProtocPlugin::Error] when the input is unreadable
14
+ def process(input)
15
+ request = Google::Protobuf::Compiler::CodeGeneratorRequest.decode(input)
16
+
17
+ response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
18
+ response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL
19
+
20
+ request.proto_file.each do |proto_file|
21
+ next unless request.file_to_generate.include?(proto_file.name)
22
+
23
+ file = Google::Protobuf::Compiler::CodeGeneratorResponse::File.new
24
+ file.name = twirp_output_filename(proto_file.name)
25
+ file.content = CodeGenerator.new(proto_file, relative_ruby_protobuf(proto_file.name)).generate
26
+
27
+ response.file << file
28
+ end
29
+
30
+ response.to_proto
31
+ end
32
+
33
+ private
34
+
35
+ # @param filename [String] a filename string (with optional path),
36
+ # e.g. "some/example/hello.proto"
37
+ # @return [String] the filename (preserving optional path) minus the file extension,
38
+ # e.g. "some/example/hello"
39
+ def strip_extension(filename)
40
+ filename.sub(/#{File.extname(filename)}$/, "")
41
+ end
42
+
43
+ # @param filename [String] the filename (with optional path) for the proto file,
44
+ # e.g. "some/example/hello.proto"
45
+ # @return [String] the output filename for the proto file's generated twirp code,
46
+ # e.g. "some/example/hello_twirp.rb"
47
+ def twirp_output_filename(filename)
48
+ strip_extension(filename) + "_twirp.rb"
49
+ end
50
+
51
+ # @param filename [String] the filename (with optional path) for the proto file,
52
+ # e.g. "some/example/hello.proto"
53
+ # @return [String] the file name of the generated ruby protobuf code from protoc,
54
+ # without any path information, minus the ".rb" extension, e.g. "hello_pb". We
55
+ # expect the generated twirp file to be in the same directory as the generated
56
+ # ruby output.
57
+ def relative_ruby_protobuf(filename)
58
+ File.basename(filename, File.extname(filename)) + "_pb" # no ".rb" extension
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Twirp
4
+ module ProtocPlugin
5
+ VERSION = "1.0.0"
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "protoc_plugin/process"
4
+ require_relative "protoc_plugin/version"
@@ -0,0 +1,180 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2008 Google Inc. All rights reserved.
3
+ //
4
+ // Use of this source code is governed by a BSD-style
5
+ // license that can be found in the LICENSE file or at
6
+ // https://developers.google.com/open-source/licenses/bsd
7
+
8
+ // Author: kenton@google.com (Kenton Varda)
9
+ //
10
+ // protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
11
+ // just a program that reads a CodeGeneratorRequest from stdin and writes a
12
+ // CodeGeneratorResponse to stdout.
13
+ //
14
+ // Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
15
+ // of dealing with the raw protocol defined here.
16
+ //
17
+ // A plugin executable needs only to be placed somewhere in the path. The
18
+ // plugin should be named "protoc-gen-$NAME", and will then be used when the
19
+ // flag "--${NAME}_out" is passed to protoc.
20
+
21
+ syntax = "proto2";
22
+
23
+ package google.protobuf.compiler;
24
+ option java_package = "com.google.protobuf.compiler";
25
+ option java_outer_classname = "PluginProtos";
26
+
27
+ option csharp_namespace = "Google.Protobuf.Compiler";
28
+ option go_package = "google.golang.org/protobuf/types/pluginpb";
29
+
30
+ import "google/protobuf/descriptor.proto";
31
+
32
+ // The version number of protocol compiler.
33
+ message Version {
34
+ optional int32 major = 1;
35
+ optional int32 minor = 2;
36
+ optional int32 patch = 3;
37
+ // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
38
+ // be empty for mainline stable releases.
39
+ optional string suffix = 4;
40
+ }
41
+
42
+ // An encoded CodeGeneratorRequest is written to the plugin's stdin.
43
+ message CodeGeneratorRequest {
44
+ // The .proto files that were explicitly listed on the command-line. The
45
+ // code generator should generate code only for these files. Each file's
46
+ // descriptor will be included in proto_file, below.
47
+ repeated string file_to_generate = 1;
48
+
49
+ // The generator parameter passed on the command-line.
50
+ optional string parameter = 2;
51
+
52
+ // FileDescriptorProtos for all files in files_to_generate and everything
53
+ // they import. The files will appear in topological order, so each file
54
+ // appears before any file that imports it.
55
+ //
56
+ // Note: the files listed in files_to_generate will include runtime-retention
57
+ // options only, but all other files will include source-retention options.
58
+ // The source_file_descriptors field below is available in case you need
59
+ // source-retention options for files_to_generate.
60
+ //
61
+ // protoc guarantees that all proto_files will be written after
62
+ // the fields above, even though this is not technically guaranteed by the
63
+ // protobuf wire format. This theoretically could allow a plugin to stream
64
+ // in the FileDescriptorProtos and handle them one by one rather than read
65
+ // the entire set into memory at once. However, as of this writing, this
66
+ // is not similarly optimized on protoc's end -- it will store all fields in
67
+ // memory at once before sending them to the plugin.
68
+ //
69
+ // Type names of fields and extensions in the FileDescriptorProto are always
70
+ // fully qualified.
71
+ repeated FileDescriptorProto proto_file = 15;
72
+
73
+ // File descriptors with all options, including source-retention options.
74
+ // These descriptors are only provided for the files listed in
75
+ // files_to_generate.
76
+ repeated FileDescriptorProto source_file_descriptors = 17;
77
+
78
+ // The version number of protocol compiler.
79
+ optional Version compiler_version = 3;
80
+ }
81
+
82
+ // The plugin writes an encoded CodeGeneratorResponse to stdout.
83
+ message CodeGeneratorResponse {
84
+ // Error message. If non-empty, code generation failed. The plugin process
85
+ // should exit with status code zero even if it reports an error in this way.
86
+ //
87
+ // This should be used to indicate errors in .proto files which prevent the
88
+ // code generator from generating correct code. Errors which indicate a
89
+ // problem in protoc itself -- such as the input CodeGeneratorRequest being
90
+ // unparseable -- should be reported by writing a message to stderr and
91
+ // exiting with a non-zero status code.
92
+ optional string error = 1;
93
+
94
+ // A bitmask of supported features that the code generator supports.
95
+ // This is a bitwise "or" of values from the Feature enum.
96
+ optional uint64 supported_features = 2;
97
+
98
+ // Sync with code_generator.h.
99
+ enum Feature {
100
+ FEATURE_NONE = 0;
101
+ FEATURE_PROTO3_OPTIONAL = 1;
102
+ FEATURE_SUPPORTS_EDITIONS = 2;
103
+ }
104
+
105
+ // The minimum edition this plugin supports. This will be treated as an
106
+ // Edition enum, but we want to allow unknown values. It should be specified
107
+ // according the edition enum value, *not* the edition number. Only takes
108
+ // effect for plugins that have FEATURE_SUPPORTS_EDITIONS set.
109
+ optional int32 minimum_edition = 3;
110
+
111
+ // The maximum edition this plugin supports. This will be treated as an
112
+ // Edition enum, but we want to allow unknown values. It should be specified
113
+ // according the edition enum value, *not* the edition number. Only takes
114
+ // effect for plugins that have FEATURE_SUPPORTS_EDITIONS set.
115
+ optional int32 maximum_edition = 4;
116
+
117
+ // Represents a single generated file.
118
+ message File {
119
+ // The file name, relative to the output directory. The name must not
120
+ // contain "." or ".." components and must be relative, not be absolute (so,
121
+ // the file cannot lie outside the output directory). "/" must be used as
122
+ // the path separator, not "\".
123
+ //
124
+ // If the name is omitted, the content will be appended to the previous
125
+ // file. This allows the generator to break large files into small chunks,
126
+ // and allows the generated text to be streamed back to protoc so that large
127
+ // files need not reside completely in memory at one time. Note that as of
128
+ // this writing protoc does not optimize for this -- it will read the entire
129
+ // CodeGeneratorResponse before writing files to disk.
130
+ optional string name = 1;
131
+
132
+ // If non-empty, indicates that the named file should already exist, and the
133
+ // content here is to be inserted into that file at a defined insertion
134
+ // point. This feature allows a code generator to extend the output
135
+ // produced by another code generator. The original generator may provide
136
+ // insertion points by placing special annotations in the file that look
137
+ // like:
138
+ // @@protoc_insertion_point(NAME)
139
+ // The annotation can have arbitrary text before and after it on the line,
140
+ // which allows it to be placed in a comment. NAME should be replaced with
141
+ // an identifier naming the point -- this is what other generators will use
142
+ // as the insertion_point. Code inserted at this point will be placed
143
+ // immediately above the line containing the insertion point (thus multiple
144
+ // insertions to the same point will come out in the order they were added).
145
+ // The double-@ is intended to make it unlikely that the generated code
146
+ // could contain things that look like insertion points by accident.
147
+ //
148
+ // For example, the C++ code generator places the following line in the
149
+ // .pb.h files that it generates:
150
+ // // @@protoc_insertion_point(namespace_scope)
151
+ // This line appears within the scope of the file's package namespace, but
152
+ // outside of any particular class. Another plugin can then specify the
153
+ // insertion_point "namespace_scope" to generate additional classes or
154
+ // other declarations that should be placed in this scope.
155
+ //
156
+ // Note that if the line containing the insertion point begins with
157
+ // whitespace, the same whitespace will be added to every line of the
158
+ // inserted text. This is useful for languages like Python, where
159
+ // indentation matters. In these languages, the insertion point comment
160
+ // should be indented the same amount as any inserted code will need to be
161
+ // in order to work correctly in that context.
162
+ //
163
+ // The code generator that generates the initial file and the one which
164
+ // inserts into it must both run as part of a single invocation of protoc.
165
+ // Code generators are executed in the order in which they appear on the
166
+ // command line.
167
+ //
168
+ // If |insertion_point| is present, |name| must also be present.
169
+ optional string insertion_point = 2;
170
+
171
+ // The file contents.
172
+ optional string content = 15;
173
+
174
+ // Information describing the file content being inserted. If an insertion
175
+ // point is used, this information will be appropriately offset and inserted
176
+ // into the code generation metadata for the generated files.
177
+ optional GeneratedCodeInfo generated_code_info = 16;
178
+ }
179
+ repeated File file = 15;
180
+ }