proto_turf 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9af9eb4df4dd0323090363e65378d08d4b9a55050eb0a08ea6ddfe2cd7bd8b59
4
- data.tar.gz: 32fb8b5f560d5e49978930f5e863d5851efc17b288f75c26e45ee7d1cf8e98dd
3
+ metadata.gz: d406d02e3db35efe7976a07238831d78ffeefc9692b6082c240aaf61983ec8be
4
+ data.tar.gz: 6ed547fb924c5d14526e22523417397b0b8b64682d4a79ca5aa78284ae940703
5
5
  SHA512:
6
- metadata.gz: 3286859be78192d3495c3dc58e15dad50273aed4d611ddf579b9b27a16b01bbf0652d17af367192ed6dd9154a693a1991342439d53bde14777a5e61e5402a036
7
- data.tar.gz: e8d941d3a7b153345e407ed62fb4e6201b93a65e01810f06cacb4fa616bbbf3c93b1456be349f3f53fd8e41d5a7f4fc4fcd0fad9fc380f8c7ff4ea101678fc18
6
+ metadata.gz: 8bd87219da56f1a9c555265dde48c7b11e86986b3e14ce4f849747054e7e5dc1c51ac64b43b584894f2215320580a72a9a159f0e94c56b868d99fc4c6ed0cc05
7
+ data.tar.gz: 43d9f128249dfc33e6f8db72a44541cc69a665e168075de1af6f40564e24c0bbdcc12587f1bdb4744ffe2606c3ff66cdc495ca08f06a6a7223c6882626d0b9be
@@ -0,0 +1,18 @@
1
+ name: Lint
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v3
12
+ - name: Set up Ruby ${{ matrix.ruby }}
13
+ uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 3.4
16
+ bundler-cache: true
17
+ - name: Run standardrb
18
+ run: bundle exec standardrb
@@ -0,0 +1,31 @@
1
+ name: Release Gem
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ tags:
7
+ - 'v*.*.*' # Matches semantic versioning tags like v1.0.0
8
+ workflow_dispatch: # Allows manual triggering of the workflow
9
+
10
+ jobs:
11
+ push:
12
+ name: Push gem to RubyGems.org
13
+ runs-on: ubuntu-latest
14
+
15
+ permissions:
16
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
17
+ contents: write # IMPORTANT: this permission is required for `rake release` to push the release tag
18
+
19
+ steps:
20
+ # Set up
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ persist-credentials: false
24
+ - name: Set up Ruby
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ bundler-cache: true
28
+ ruby-version: ruby
29
+
30
+ # Release
31
+ - uses: rubygems/release-gem@v1
@@ -0,0 +1,22 @@
1
+ name: Test
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: [3.1, 3.2, 3.3, 3.4]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - name: Set up Ruby ${{ matrix.ruby }}
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby }}
20
+ bundler-cache: true
21
+ - name: Build and test with RSpec
22
+ run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
- # 0.0.3 - 2025-8-15
10
+ # 0.0.4 - 2025-08-19
11
+
12
+ * Changed emitting of protobuf schemas from file-based to generated from descriptors.
13
+
14
+ # 0.0.3 - 2025-08-15
11
15
 
12
16
  * Initial release.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- proto_turf (0.0.2)
4
+ proto_turf (0.0.4)
5
5
  excon
6
6
  google-protobuf
7
7
 
@@ -21,6 +21,9 @@ GEM
21
21
  google-protobuf (4.30.2-arm64-darwin)
22
22
  bigdecimal
23
23
  rake (>= 13)
24
+ google-protobuf (4.30.2-x86_64-linux)
25
+ bigdecimal
26
+ rake (>= 13)
24
27
  hashdiff (1.2.0)
25
28
  json (2.13.2)
26
29
  language_server-protocol (3.17.0.5)
@@ -93,6 +96,7 @@ GEM
93
96
 
94
97
  PLATFORMS
95
98
  arm64-darwin
99
+ x86_64-linux
96
100
 
97
101
  DEPENDENCIES
98
102
  bundler (~> 2.0)
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
@@ -0,0 +1,315 @@
1
+ class ProtoTurf
2
+ module ProtoText
3
+ ParseInfo = Struct.new(:writer, :package, :message) do
4
+ %i[write write_indent write_line writenl indent dedent].each do |method|
5
+ define_method(method) do |*args|
6
+ writer.send(method, *args)
7
+ end
8
+ end
9
+ end
10
+
11
+ class Writer < StringIO
12
+ def initialize(...)
13
+ super
14
+ @indent = 0
15
+ end
16
+
17
+ def write_indent(str)
18
+ @indent.times { write(" ") }
19
+ write(str)
20
+ end
21
+
22
+ def write_line(line, nl = 1)
23
+ write_indent(line)
24
+ nl.times { writenl }
25
+ end
26
+
27
+ def writenl
28
+ write("\n")
29
+ end
30
+
31
+ def indent
32
+ @indent += 2
33
+ end
34
+
35
+ def dedent
36
+ @indent -= 2
37
+ end
38
+ end
39
+
40
+ class << self
41
+ def fetch(message_name)
42
+ name = message_name.start_with?(".") ? message_name[1..] : message_name
43
+ Google::Protobuf::DescriptorPool.generated_pool.lookup(name)
44
+ end
45
+
46
+ def output(file_descriptor)
47
+ writer = Writer.new
48
+ info = ParseInfo.new(writer, file_descriptor.package)
49
+ writer.write_line("syntax = \"#{file_descriptor.syntax}\";", 2)
50
+ writer.write_line("package #{file_descriptor.package};")
51
+ writer.writenl
52
+ found = false
53
+ file_descriptor.options.to_h.each do |name, value|
54
+ found = true
55
+ writer.write_line("option #{name} = #{value.to_json};")
56
+ end
57
+ writer.writenl if found
58
+
59
+ found = false
60
+ file_descriptor.dependency.each do |dependency|
61
+ found = true
62
+ writer.write_line("import \"#{dependency}\";")
63
+ end
64
+ writer.writenl if found
65
+
66
+ writer.writenl if write_options(info, file_descriptor)
67
+ writer.writenl if write_extensions(info, file_descriptor)
68
+
69
+ file_descriptor.enum_type.each do |enum_type|
70
+ write_enum(info, enum_type)
71
+ end
72
+ file_descriptor.message_type.each do |message_type|
73
+ write_message(info, message_type)
74
+ end
75
+ file_descriptor.service.each do |service|
76
+ write_service(info, service)
77
+ end
78
+ writer.string
79
+ end
80
+
81
+ def write_extensions(info, descriptor)
82
+ descriptor.extension.each do |extension|
83
+ info.write_line("extend #{extension.extendee[1..]} {")
84
+ info.indent
85
+ write_field(info, extension)
86
+ info.dedent
87
+ info.write_line("}")
88
+ end
89
+ descriptor.extension.any?
90
+ end
91
+
92
+ def write_reserved(writer, descriptor)
93
+ reserved = descriptor.reserved_range.map do |range|
94
+ (range.start == range.end - 1) ? range.start.to_s : "#{range.start} to #{range.end - 1}"
95
+ end
96
+ found = false
97
+ if reserved.any?
98
+ found = true
99
+ writer.write_line("reserved #{reserved.join(", ")};")
100
+ end
101
+ if descriptor.reserved_name.any?
102
+ found = true
103
+ writer.write_line("reserved #{descriptor.reserved_name.map(&:to_json).join(", ")};")
104
+ end
105
+ writer.writenl if found
106
+ end
107
+
108
+ def write_imports(writer, file_descriptor)
109
+ writer.writenl
110
+ file_descriptor.dependency.each do |dependency|
111
+ writer.write_line("import \"#{dependency}\";")
112
+ end
113
+ file_descriptor.public_dependency.each do |public_dependency|
114
+ writer.write_line("import public \"#{public_dependency}\";")
115
+ end
116
+ file_descriptor.option_dependency.each do |option_dependency|
117
+ writer.write_line("import weak \"#{option_dependency}\";")
118
+ end
119
+ writer.writenl
120
+ end
121
+
122
+ def write_message(info, message_type)
123
+ info.message = message_type
124
+ info.write_indent("message ")
125
+ info.write("#{message_type.name} {")
126
+ info.writenl
127
+ info.indent
128
+
129
+ write_options(info, message_type)
130
+ write_reserved(info, message_type)
131
+
132
+ message_type.enum_type.each do |enum|
133
+ info.writenl
134
+ write_enum(info, enum)
135
+ end
136
+ message_type.field.each do |field|
137
+ write_field(info, field)
138
+ end
139
+ message_type.extension.each do |extension|
140
+ write_field(info, extension)
141
+ end
142
+ write_oneofs(info, message_type)
143
+ message_type.nested_type.each do |subtype|
144
+ info.writenl
145
+ write_message(info, subtype)
146
+ end
147
+ info.dedent
148
+ info.write_line("}")
149
+ end
150
+
151
+ def field_type(info, field_type)
152
+ case field_type.type
153
+ when :TYPE_INT32
154
+ "int32"
155
+ when :TYPE_INT64
156
+ "int64"
157
+ when :TYPE_UINT32
158
+ "uint32"
159
+ when :TYPE_UINT64
160
+ "uint64"
161
+ when :TYPE_SINT32
162
+ "sint32"
163
+ when :TYPE_SINT64
164
+ "sint64"
165
+ when :TYPE_FIXED32
166
+ "fixed32"
167
+ when :TYPE_FIXED64
168
+ "fixed64"
169
+ when :TYPE_SFIXED32
170
+ "sfixed32"
171
+ when :TYPE_SFIXED64
172
+ "sfixed64"
173
+ when :TYPE_FLOAT
174
+ "float"
175
+ when :TYPE_DOUBLE
176
+ "double"
177
+ when :TYPE_BOOL
178
+ "bool"
179
+ when :TYPE_STRING
180
+ "string"
181
+ when :TYPE_BYTES
182
+ "bytes"
183
+ when :TYPE_ENUM, :TYPE_MESSAGE
184
+ # remove leading .
185
+ type = fetch(field_type.type_name[1..])
186
+ name = type.name.sub("#{info.package}.#{info.message.name}.", "")
187
+ name.sub("#{info.package}.", "")
188
+ end
189
+ end
190
+
191
+ def write_field(info, field, oneof: false)
192
+ info.write_indent("")
193
+ return if !oneof && field.has_oneof_index?
194
+
195
+ klass = nil
196
+ if field.type_name && field.type_name != ""
197
+ klass = fetch(field.type_name).to_proto
198
+ end
199
+
200
+ if field.proto3_optional
201
+ info.write("optional ")
202
+ elsif field.label == :LABEL_REPEATED && !klass&.options&.map_entry
203
+ info.write("repeated ")
204
+ end
205
+
206
+ if klass&.options&.map_entry
207
+ info.write("map<#{field_type(info, klass.field[0])}, #{field_type(info, klass.field[1])}>")
208
+ else
209
+ info.write(field_type(info, field).to_s)
210
+ end
211
+ info.write(" #{field.name} = #{field.number}")
212
+
213
+ write_field_options(info, field)
214
+ info.write(";")
215
+ info.writenl
216
+ end
217
+
218
+ def write_field_options(info, field)
219
+ return unless field.options
220
+
221
+ info.write(" [")
222
+ info.write(field.options.to_h.map { |name, value| "#{name} = #{value}" }.join(", "))
223
+ write_options(info, field, include_option_label: false)
224
+ info.write("]")
225
+ end
226
+
227
+ def write_oneofs(info, message)
228
+ message.oneof_decl.each_with_index do |oneof, i|
229
+ next if oneof.name.start_with?("_") &&
230
+ message.field.any? { |f| f.proto3_optional && f.name == oneof.name[1..] }
231
+ info.write_line("oneof #{oneof.name} {")
232
+ info.indent
233
+ message.field.select { |f| f.has_oneof_index? && f.oneof_index == i }.each do |field|
234
+ write_field(info, field, oneof: true)
235
+ end
236
+ info.dedent
237
+ info.write_line("}")
238
+ end
239
+ end
240
+
241
+ def write_enum(info, enum_type)
242
+ info.write("enum ")
243
+ info.write("#{enum_type.name} {")
244
+ info.writenl
245
+ info.indent
246
+ write_reserved(info, enum_type)
247
+ enum_type.value.each do |value|
248
+ info.write_line("#{value.name} = #{value.number};")
249
+ end
250
+ info.dedent
251
+ info.write_line("}")
252
+ info.writenl
253
+ end
254
+
255
+ def method_type(package, name)
256
+ output = name.sub("#{package}.", "")
257
+ output = output[1..] if output.start_with?(".")
258
+ output
259
+ end
260
+
261
+ def write_service(info, service)
262
+ info.write_line("service #{service.name} {")
263
+ info.indent
264
+ service["method"].each do |method|
265
+ info.write_indent("rpc #{method.name}(#{method_type(info.package, method.input_type)}) ")
266
+ info.write("returns (#{method_type(info.package, method.output_type)}) {")
267
+ info.writenl
268
+ info.indent
269
+ if method.options
270
+ write_options(info, method)
271
+ end
272
+ info.dedent
273
+ info.write_line("};")
274
+ end
275
+ info.dedent
276
+ info.write_line("}")
277
+ end
278
+
279
+ # @return [Boolean] true if any options were written
280
+ def write_options(info, descriptor, include_option_label: true)
281
+ # unfortunately there doesn't seem to be a way to get the full list of options without
282
+ # resorting to to_json.
283
+ json = JSON.parse(descriptor.options.to_json)
284
+ return if !json || json.empty?
285
+
286
+ found = false
287
+ json.keys.each do |name|
288
+ option_name = name.tr("[]", "")
289
+ ext = fetch(option_name)
290
+ next if ext.nil?
291
+
292
+ found = true
293
+ options = ext.get(descriptor.options)
294
+ if include_option_label
295
+ info.write_indent("option (#{option_name}) =")
296
+ else
297
+ info.write("(#{option_name}) = ")
298
+ end
299
+ if options.respond_to?(:to_h)
300
+ lines = JSON.pretty_generate(options.to_h).lines(chomp: true)
301
+ lines.each_with_index do |line, i|
302
+ info.write_indent(line)
303
+ info.writenl if i < lines.length - 1
304
+ end
305
+ info.write(";")
306
+ else
307
+ info.write(options.to_json)
308
+ end
309
+ info.writenl
310
+ end
311
+ found
312
+ end
313
+ end
314
+ end
315
+ end
@@ -1,3 +1,3 @@
1
1
  class ProtoTurf
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/proto_turf.rb CHANGED
@@ -5,6 +5,7 @@ require "google/protobuf/descriptor_pb"
5
5
  require "json"
6
6
  require "proto_turf/confluent_schema_registry"
7
7
  require "proto_turf/cached_confluent_schema_registry"
8
+ require "proto_turf/proto_text"
8
9
 
9
10
  class ProtoTurf
10
11
  # Provides a way to encode and decode messages without having to embed schemas
@@ -25,7 +26,6 @@ class ProtoTurf
25
26
  # ProtoTurf::ConfluentSchemaRegistry interface.
26
27
  # registry_url - The String URL of the schema registry that should be used.
27
28
  # schema_context - Schema registry context name (optional)
28
- # schema_paths - The String file system path where local schemas are stored.
29
29
  # registry_path_prefix - The String URL path prefix used to namespace schema registry requests (optional).
30
30
  # logger - The Logger that should be used to log information (optional).
31
31
  # proxy - Forward the request via proxy (optional).
@@ -43,7 +43,6 @@ class ProtoTurf
43
43
  registry: nil,
44
44
  registry_url: nil,
45
45
  schema_context: nil,
46
- schema_paths: nil,
47
46
  registry_path_prefix: nil,
48
47
  logger: nil,
49
48
  proxy: nil,
@@ -60,7 +59,6 @@ class ProtoTurf
60
59
  retry_limit: nil
61
60
  )
62
61
  @logger = logger || Logger.new($stderr)
63
- @paths = Array(schema_paths)
64
62
  @registry = registry || ProtoTurf::CachedConfluentSchemaRegistry.new(
65
63
  ProtoTurf::ConfluentSchemaRegistry.new(
66
64
  registry_url,
@@ -252,19 +250,12 @@ class ProtoTurf
252
250
  end
253
251
 
254
252
  def schema_text(file_descriptor)
255
- @paths.each do |path|
256
- filename = "#{path}/#{file_descriptor.name}"
257
- return File.read(filename) if File.exist?(filename)
258
- end
259
- ""
253
+ ProtoTurf::ProtoText.output(file_descriptor.to_proto)
260
254
  end
261
255
 
262
256
  def load_schemas!
263
- all_messages = ObjectSpace.each_object(Class).select do |o|
264
- o < Google::Protobuf.const_get(:AbstractMessage)
265
- end.to_a
266
- all_messages.each do |m|
267
- file_desc = m.descriptor.file_descriptor
257
+ all_files = ObjectSpace.each_object(Google::Protobuf::FileDescriptor).to_a
258
+ all_files.each do |file_desc|
268
259
  file_path = file_desc.name
269
260
  next if file_path.start_with?("google/protobuf/") # skip built-in protos
270
261
 
@@ -1,8 +1,7 @@
1
1
  RSpec.describe "encoding" do
2
2
  let(:proto_turf) do
3
3
  ProtoTurf.new(
4
- registry_url: "http://localhost:8081",
5
- schema_paths: ["spec/schemas"]
4
+ registry_url: "http://localhost:8081"
6
5
  )
7
6
  end
8
7
 
@@ -1,8 +1,7 @@
1
1
  RSpec.describe "encoding" do
2
2
  let(:proto_turf) do
3
3
  ProtoTurf.new(
4
- registry_url: "http://localhost:8081",
5
- schema_paths: ["spec/schemas"]
4
+ registry_url: "http://localhost:8081"
6
5
  )
7
6
  end
8
7
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
4
+ # source: everything/everything.proto
5
+
6
+ require "google/protobuf"
7
+
8
+ require "simple/simple_pb"
9
+ require "google/protobuf/descriptor_pb"
10
+
11
+ descriptor_data = "\n\x1b\x65verything/everything.proto\x12\reverything.v1\x1a\x13simple/simple.proto\x1a google/protobuf/descriptor.proto\"*\n\x0e\x46oreignMessage\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xc0\x12\n\x0cTestAllTypes\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05\x12\x16\n\x0eoptional_int64\x18\x02 \x01(\x03\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x17\n\x0foptional_uint64\x18\x04 \x01(\x04\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_sint64\x18\x06 \x01(\x12\x12\x18\n\x10optional_fixed32\x18\x07 \x01(\x07\x12\x18\n\x10optional_fixed64\x18\x08 \x01(\x06\x12\x19\n\x11optional_sfixed32\x18\t \x01(\x0f\x12\x19\n\x11optional_sfixed64\x18\n \x01(\x10\x12\x16\n\x0eoptional_float\x18\x0b \x01(\x02\x12\x17\n\x0foptional_double\x18\x0c \x01(\x01\x12\x15\n\roptional_bool\x18\r \x01(\x08\x12\x17\n\x0foptional_string\x18\x0e \x01(\t\x12\x16\n\x0eoptional_bytes\x18\x0f \x01(\x0c\x12J\n\x17optional_nested_message\x18\x12 \x01(\x0b\x32).everything.v1.TestAllTypes.NestedMessage\x12?\n\x18optional_foreign_message\x18\x13 \x01(\x0b\x32\x1d.everything.v1.ForeignMessage\x12\x39\n\x17optional_import_message\x18\x14 \x01(\x0b\x32\x18.simple.v1.SimpleMessage\x12\x44\n\x14optional_nested_enum\x18\x15 \x01(\x0e\x32&.everything.v1.TestAllTypes.NestedEnum\x12\x39\n\x15optional_foreign_enum\x18\x16 \x01(\x0e\x32\x1a.everything.v1.ForeignEnum\x12\x33\n\x14optional_import_enum\x18\x17 \x01(\x0e\x32\x15.simple.v1.SimpleEnum\x12!\n\x15optional_string_piece\x18\x18 \x01(\tB\x02\x08\x02\x12\x19\n\roptional_cord\x18\x19 \x01(\tB\x02\x08\x01\x12\x1f\n\x13optional_bytes_cord\x18V \x01(\x0c\x42\x02\x08\x01\x12L\n\x15optional_lazy_message\x18\x1b \x01(\x0b\x32).everything.v1.TestAllTypes.NestedMessageB\x02(\x01\x12W\n optional_unverified_lazy_message\x18\x1c \x01(\x0b\x32).everything.v1.TestAllTypes.NestedMessageB\x02x\x01\x12\x16\n\x0erepeated_int32\x18\x1f \x03(\x05\x12\x16\n\x0erepeated_int64\x18 \x03(\x03\x12\x17\n\x0frepeated_uint32\x18! \x03(\r\x12\x17\n\x0frepeated_uint64\x18\" \x03(\x04\x12\x17\n\x0frepeated_sint32\x18# \x03(\x11\x12\x17\n\x0frepeated_sint64\x18$ \x03(\x12\x12\x18\n\x10repeated_fixed32\x18% \x03(\x07\x12\x18\n\x10repeated_fixed64\x18& \x03(\x06\x12\x19\n\x11repeated_sfixed32\x18' \x03(\x0f\x12\x19\n\x11repeated_sfixed64\x18( \x03(\x10\x12\x16\n\x0erepeated_float\x18) \x03(\x02\x12\x17\n\x0frepeated_double\x18* \x03(\x01\x12\x15\n\rrepeated_bool\x18+ \x03(\x08\x12\x17\n\x0frepeated_string\x18, \x03(\t\x12\x16\n\x0erepeated_bytes\x18- \x03(\x0c\x12J\n\x17repeated_nested_message\x18\x30 \x03(\x0b\x32).everything.v1.TestAllTypes.NestedMessage\x12?\n\x18repeated_foreign_message\x18\x31 \x03(\x0b\x32\x1d.everything.v1.ForeignMessage\x12\x39\n\x17repeated_import_message\x18\x32 \x03(\x0b\x32\x18.simple.v1.SimpleMessage\x12\x44\n\x14repeated_nested_enum\x18\x33 \x03(\x0e\x32&.everything.v1.TestAllTypes.NestedEnum\x12\x39\n\x15repeated_foreign_enum\x18\x34 \x03(\x0e\x32\x1a.everything.v1.ForeignEnum\x12\x33\n\x14repeated_import_enum\x18\x35 \x03(\x0e\x32\x15.simple.v1.SimpleEnum\x12!\n\x15repeated_string_piece\x18\x36 \x03(\tB\x02\x08\x02\x12\x19\n\rrepeated_cord\x18\x37 \x03(\tB\x02\x08\x01\x12L\n\x15repeated_lazy_message\x18\x39 \x03(\x0b\x32).everything.v1.TestAllTypes.NestedMessageB\x02(\x01\x12\x16\n\x0coneof_uint32\x18o \x01(\rH\x00\x12I\n\x14oneof_nested_message\x18p \x01(\x0b\x32).everything.v1.TestAllTypes.NestedMessageH\x00\x12\x16\n\x0coneof_string\x18q \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18r \x01(\x0cH\x00\x12\x18\n\noneof_cord\x18s \x01(\tB\x02\x08\x01H\x00\x12 \n\x12oneof_string_piece\x18t \x01(\tB\x02\x08\x02H\x00\x12R\n\x19oneof_lazy_nested_message\x18u \x01(\x0b\x32).everything.v1.TestAllTypes.NestedMessageB\x02(\x01H\x00\x1a\"\n\rNestedMessage\x12\x11\n\x02\x62\x62\x18\x01 \x01(\x05\x42\x05\x90\x82\x19\xd2\t\x1a\x1a\n\rOptionalGroup\x12\t\n\x01\x61\x18\x11 \x01(\x05\x1a\x1a\n\rRepeatedGroup\x12\t\n\x01\x61\x18/ \x01(\x05\"'\n\nNestedEnum\x12\x07\n\x03\x46OO\x10\x00\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03\x42\x41Z\x10\x03\x42\r\n\x0boneof_field*/\n\x0b\x46oreignEnum\x12\x0f\n\x0b\x46OREIGN_FOO\x10\x00\x12\x0f\n\x0b\x46OREIGN_BAR\x10\x01\x32Y\n\x0bTestService\x12J\n\nTestMethod\x12\x1b.everything.v1.TestAllTypes\x1a\x1d.everything.v1.ForeignMessage\"\x00:4\n\x0bsome_option\x12\x1d.google.protobuf.FieldOptions\x18\xa2\x90\x03 \x01(\x05\x62\x06proto3"
12
+
13
+ pool = Google::Protobuf::DescriptorPool.generated_pool
14
+ pool.add_serialized_file(descriptor_data)
15
+
16
+ module Everything
17
+ module V1
18
+ ForeignMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.ForeignMessage").msgclass
19
+ TestAllTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.TestAllTypes").msgclass
20
+ TestAllTypes::NestedMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.TestAllTypes.NestedMessage").msgclass
21
+ TestAllTypes::OptionalGroup = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.TestAllTypes.OptionalGroup").msgclass
22
+ TestAllTypes::RepeatedGroup = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.TestAllTypes.RepeatedGroup").msgclass
23
+ TestAllTypes::NestedEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.TestAllTypes.NestedEnum").enummodule
24
+ ForeignEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("everything.v1.ForeignEnum").enummodule
25
+ end
26
+ end
@@ -5,7 +5,7 @@
5
5
 
6
6
  require "google/protobuf"
7
7
 
8
- descriptor_data = "\n\x13simple/simple.proto\x12\tsimple.v1\"\x1d\n\rSimpleMessage\x12\x0c\n\x04name\x18\x01 \x01(\tb\x06proto3"
8
+ descriptor_data = "\n\x13simple/simple.proto\x12\tsimple.v1\"\x1d\n\rSimpleMessage\x12\x0c\n\x04name\x18\x01 \x01(\t*,\n\nSimpleEnum\x12\x0e\n\nSIMPLE_FOO\x10\x00\x12\x0e\n\nSIMPLE_BAR\x10\x01\x62\x06proto3"
9
9
 
10
10
  pool = Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
@@ -13,5 +13,6 @@ pool.add_serialized_file(descriptor_data)
13
13
  module Simple
14
14
  module V1
15
15
  SimpleMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("simple.v1.SimpleMessage").msgclass
16
+ SimpleEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("simple.v1.SimpleEnum").enummodule
16
17
  end
17
18
  end
@@ -0,0 +1,8 @@
1
+ RSpec.describe ProtoTurf::ProtoText do
2
+ it "should output as expected" do
3
+ output = described_class.output(Everything::V1::TestAllTypes.descriptor.file_descriptor.to_proto)
4
+
5
+ expected = File.read("#{__dir__}/schemas/everything/everything.proto")
6
+ expect(output).to eq(expected)
7
+ end
8
+ end
@@ -0,0 +1,105 @@
1
+ syntax = "proto3";
2
+
3
+ package everything.v1;
4
+
5
+ import "simple/simple.proto";
6
+ import "google/protobuf/descriptor.proto";
7
+
8
+ extend google.protobuf.FieldOptions {
9
+ int32 some_option = 51234;
10
+ }
11
+
12
+ enum ForeignEnum {
13
+ FOREIGN_FOO = 0;
14
+ FOREIGN_BAR = 1;
15
+ }
16
+
17
+ message ForeignMessage {
18
+ int32 id = 1;
19
+ string name = 2;
20
+ }
21
+ message TestAllTypes {
22
+
23
+ enum NestedEnum {
24
+ FOO = 0;
25
+ BAR = 2;
26
+ BAZ = 3;
27
+ }
28
+
29
+ int32 optional_int32 = 1;
30
+ int64 optional_int64 = 2;
31
+ uint32 optional_uint32 = 3;
32
+ uint64 optional_uint64 = 4;
33
+ sint32 optional_sint32 = 5;
34
+ sint64 optional_sint64 = 6;
35
+ fixed32 optional_fixed32 = 7;
36
+ fixed64 optional_fixed64 = 8;
37
+ sfixed32 optional_sfixed32 = 9;
38
+ sfixed64 optional_sfixed64 = 10;
39
+ float optional_float = 11;
40
+ double optional_double = 12;
41
+ bool optional_bool = 13;
42
+ string optional_string = 14;
43
+ bytes optional_bytes = 15;
44
+ NestedMessage optional_nested_message = 18;
45
+ ForeignMessage optional_foreign_message = 19;
46
+ simple.v1.SimpleMessage optional_import_message = 20;
47
+ NestedEnum optional_nested_enum = 21;
48
+ ForeignEnum optional_foreign_enum = 22;
49
+ simple.v1.SimpleEnum optional_import_enum = 23;
50
+ string optional_string_piece = 24 [ctype = STRING_PIECE];
51
+ string optional_cord = 25 [ctype = CORD];
52
+ bytes optional_bytes_cord = 86 [ctype = CORD];
53
+ NestedMessage optional_lazy_message = 27 [lazy = true];
54
+ NestedMessage optional_unverified_lazy_message = 28 [unverified_lazy = true];
55
+ repeated int32 repeated_int32 = 31;
56
+ repeated int64 repeated_int64 = 32;
57
+ repeated uint32 repeated_uint32 = 33;
58
+ repeated uint64 repeated_uint64 = 34;
59
+ repeated sint32 repeated_sint32 = 35;
60
+ repeated sint64 repeated_sint64 = 36;
61
+ repeated fixed32 repeated_fixed32 = 37;
62
+ repeated fixed64 repeated_fixed64 = 38;
63
+ repeated sfixed32 repeated_sfixed32 = 39;
64
+ repeated sfixed64 repeated_sfixed64 = 40;
65
+ repeated float repeated_float = 41;
66
+ repeated double repeated_double = 42;
67
+ repeated bool repeated_bool = 43;
68
+ repeated string repeated_string = 44;
69
+ repeated bytes repeated_bytes = 45;
70
+ repeated NestedMessage repeated_nested_message = 48;
71
+ repeated ForeignMessage repeated_foreign_message = 49;
72
+ repeated simple.v1.SimpleMessage repeated_import_message = 50;
73
+ repeated NestedEnum repeated_nested_enum = 51;
74
+ repeated ForeignEnum repeated_foreign_enum = 52;
75
+ repeated simple.v1.SimpleEnum repeated_import_enum = 53;
76
+ repeated string repeated_string_piece = 54 [ctype = STRING_PIECE];
77
+ repeated string repeated_cord = 55 [ctype = CORD];
78
+ repeated NestedMessage repeated_lazy_message = 57 [lazy = true];
79
+ oneof oneof_field {
80
+ uint32 oneof_uint32 = 111;
81
+ NestedMessage oneof_nested_message = 112;
82
+ string oneof_string = 113;
83
+ bytes oneof_bytes = 114;
84
+ string oneof_cord = 115 [ctype = CORD];
85
+ string oneof_string_piece = 116 [ctype = STRING_PIECE];
86
+ NestedMessage oneof_lazy_nested_message = 117 [lazy = true];
87
+ }
88
+
89
+ message NestedMessage {
90
+ int32 bb = 1 [(everything.v1.some_option) = 1234
91
+ ];
92
+ }
93
+
94
+ message OptionalGroup {
95
+ int32 a = 17;
96
+ }
97
+
98
+ message RepeatedGroup {
99
+ int32 a = 47;
100
+ }
101
+ }
102
+ service TestService {
103
+ rpc TestMethod(TestAllTypes) returns (ForeignMessage) {
104
+ };
105
+ }
@@ -1,23 +1,27 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package referenced.v1;
4
+
4
5
  import "simple/simple.proto";
5
6
 
6
7
  message MessageA {
8
+
7
9
  message MessageAA {
8
10
  string name = 1;
9
11
  simple.v1.SimpleMessage simple = 2;
10
12
  }
13
+
11
14
  message MessageAB {
12
15
  string name = 1;
13
16
  }
14
17
  }
15
-
16
18
  message MessageB {
19
+
17
20
  message MessageBA {
18
21
  string name = 1;
19
22
  simple.v1.SimpleMessage simple = 2;
20
23
  }
24
+
21
25
  message MessageBB {
22
26
  string name = 1;
23
27
  }
@@ -2,6 +2,11 @@ syntax = "proto3";
2
2
 
3
3
  package simple.v1;
4
4
 
5
+ enum SimpleEnum {
6
+ SIMPLE_FOO = 0;
7
+ SIMPLE_BAR = 1;
8
+ }
9
+
5
10
  message SimpleMessage {
6
11
  string name = 1;
7
12
  }
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proto_turf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-08-15 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: google-protobuf
@@ -108,28 +107,35 @@ dependencies:
108
107
  - - ">="
109
108
  - !ruby/object:Gem::Version
110
109
  version: '0'
111
- description:
112
110
  email:
113
111
  - daniel.orner@flipp.com
114
112
  executables: []
115
113
  extensions: []
116
114
  extra_rdoc_files: []
117
115
  files:
116
+ - ".github/workflows/lint.yml"
117
+ - ".github/workflows/release.yml"
118
+ - ".github/workflows/test.yml"
118
119
  - ".rspec"
119
120
  - CHANGELOG.md
120
121
  - Gemfile
121
122
  - Gemfile.lock
122
123
  - LICENSE
123
124
  - README.md
125
+ - Rakefile
124
126
  - lib/proto_turf.rb
125
127
  - lib/proto_turf/cached_confluent_schema_registry.rb
126
128
  - lib/proto_turf/confluent_schema_registry.rb
129
+ - lib/proto_turf/proto_text.rb
127
130
  - lib/proto_turf/version.rb
128
131
  - proto_turf.gemspec
129
132
  - spec/decoding_spec.rb
130
133
  - spec/encoding_spec.rb
134
+ - spec/gen/everything/everything_pb.rb
131
135
  - spec/gen/referenced/referer_pb.rb
132
136
  - spec/gen/simple/simple_pb.rb
137
+ - spec/proto_text_spec.rb
138
+ - spec/schemas/everything/everything.proto
133
139
  - spec/schemas/referenced/referer.proto
134
140
  - spec/schemas/simple/simple.proto
135
141
  - spec/spec_helper.rb
@@ -138,7 +144,6 @@ licenses:
138
144
  - MIT
139
145
  metadata:
140
146
  rubygems_mfa_required: 'true'
141
- post_install_message:
142
147
  rdoc_options: []
143
148
  require_paths:
144
149
  - lib
@@ -153,8 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
158
  - !ruby/object:Gem::Version
154
159
  version: '0'
155
160
  requirements: []
156
- rubygems_version: 3.4.10
157
- signing_key:
161
+ rubygems_version: 3.6.9
158
162
  specification_version: 4
159
163
  summary: Support for Protobuf files in Confluent Schema Registry
160
164
  test_files: []