protoc-gen-twirp_ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.standard.yml +6 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE +21 -0
- data/README.md +69 -0
- data/Rakefile +10 -0
- data/example/hello_world.proto +14 -0
- data/example/hello_world_pb.rb +39 -0
- data/example/hello_world_twirp.rb +21 -0
- data/exe/protoc-gen-twirp_ruby +7 -0
- data/lib/google/protobuf/compiler/plugin_pb.rb +47 -0
- data/lib/google/protobuf/descriptor_pb.rb +86 -0
- data/lib/twirp/protoc_plugin/code_generator.rb +201 -0
- data/lib/twirp/protoc_plugin/process.rb +62 -0
- data/lib/twirp/protoc_plugin/version.rb +7 -0
- data/lib/twirp/protoc_plugin.rb +4 -0
- data/proto/google/protobuf/compiler/plugin.proto +180 -0
- data/proto/google/protobuf/descriptor.proto +1280 -0
- data/sig/twirp/protoc_plugin.rbs +6 -0
- metadata +152 -0
@@ -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,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
|
+
}
|