proto_turf 0.0.1 → 0.0.2

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: 748636abfd68b4fbf48cb1786c3d2617ae0b48400c23e14c9ff03786601a4dd8
4
- data.tar.gz: 9b3e76306ecefa2cfe6ca7b097b366d8145ec4c3a2c1dbe59b05625b1d1b37e7
3
+ metadata.gz: a059f77cfc5a504cf09140a84a578a3609ef40c83074897f8dda0eb42bcc011e
4
+ data.tar.gz: 1f0156bec33ddd18a48d90a3500b20066bf3a99a57627ef5a811e4efe439a60f
5
5
  SHA512:
6
- metadata.gz: 58e153ed45709e81d7b1d6d2b35523282d866a20f925e549ace5930daf29d1f2afafadcdd48b383bc7f27e662e401aa72cabc7cbd9e4a3d5bc3abad3f121f0d2
7
- data.tar.gz: 5715d4b57c35db06292f30ec6228a19d4e089e65558cf0e2c0c698ec930fc471541a1b92d9743344a173a6b7b67ba2c8593bbe198bca5eb58841112d8f5339ce
6
+ metadata.gz: 6d7d01d659d17256f3cb3bcba5abb9a1b5634c0e423cb7a0b603855ddbd3c26abb882ca8ae23e651fa5b1e7d39286ff024933fb31c058b57a6077d5b6a4f37ae
7
+ data.tar.gz: eab1c0e1e9b220a1eb1a9adf2b969adde64298d248816faffa9ed96f15d0ca565997d9d7e201f8d4fef5fe7cf3d128d971720b3393532fb083704bf1ca640774
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## UNRELEASED
9
+
10
+ # 0.0.2 - 2025-8-14
11
+
12
+ * Initial release.
data/README.md CHANGED
@@ -40,9 +40,5 @@ If you're using [buf](https://buf.build/) to manage your Protobuf definitions, y
40
40
 
41
41
  ## Notes about usage
42
42
 
43
- * For now, this library only supports a single message per `.proto` file that is registered with the Schema Registry. You can reference as many other files and messages as you like from that message, but keeping it to one message per file simplifies the workflow significantly.
44
43
  * When decoding, this library does *not* attempt to fully parse the Proto definition stored on the schema registry and generate dynamic classes. Instead, it simply parses out the package and message and assumes that the reader has the message available in the descriptor pool. Any compatibility issues should be detected through normal means, i.e. just by instantiating the message and seeing if any errors are raised.
45
44
 
46
- ## TODO
47
-
48
- * Support multi-message proto files
@@ -1,3 +1,3 @@
1
1
  class ProtoTurf
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/proto_turf.rb CHANGED
@@ -90,7 +90,8 @@ class ProtoTurf
90
90
  def encode(message, subject: nil)
91
91
  load_schemas! if @all_schemas.empty?
92
92
 
93
- id = register_schema(message.class.descriptor.file_descriptor, subject: subject)
93
+ file_descriptor = message.class.descriptor.file_descriptor
94
+ id = register_schema(file_descriptor, subject: subject)
94
95
 
95
96
  stream = StringIO.new
96
97
  # Always start with the magic byte.
@@ -99,9 +100,15 @@ class ProtoTurf
99
100
  # The schema id is encoded as a 4-byte big-endian integer.
100
101
  stream.write([id].pack("N"))
101
102
 
102
- # For now, we're only going to support a single message per schema. See
103
- # https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#wire-format
104
- write_int(stream, 0)
103
+ _, indexes = find_index(message.class.descriptor.to_proto,
104
+ file_descriptor.to_proto.message_type)
105
+
106
+ if indexes == [0]
107
+ write_int(stream, 0)
108
+ else
109
+ write_int(stream, indexes.length)
110
+ indexes.each { |i| write_int(stream, i) }
111
+ end
105
112
 
106
113
  # Now we write the actual message.
107
114
  stream.write(message.to_proto)
@@ -135,17 +142,49 @@ class ProtoTurf
135
142
 
136
143
  # For now, we're only going to support a single message per schema. See
137
144
  # https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#wire-format
138
- read_int(stream)
145
+ index_length = read_int(stream)
146
+ indexes = []
147
+ if index_length.zero?
148
+ indexes.push(0)
149
+ else
150
+ index_length.times do
151
+ indexes.push(read_int(stream))
152
+ end
153
+ end
139
154
 
140
155
  schema = @registry.fetch(schema_id)
141
156
  encoded = stream.read
142
- decode_protobuf(schema, encoded)
157
+ decode_protobuf(schema, encoded, indexes)
143
158
  rescue Excon::Error::NotFound
144
159
  raise SchemaNotFoundError.new("Schema with id: #{schema_id} is not found on registry")
145
160
  end
146
161
 
147
162
  private
148
163
 
164
+ def find_index(descriptor, messages, indexes=[])
165
+ messages.each_with_index do |sub_descriptor, i|
166
+ if sub_descriptor == descriptor
167
+ indexes.push(i)
168
+ return [true, indexes]
169
+ else
170
+ found, found_indexes = find_index(descriptor, sub_descriptor.nested_type, indexes + [i])
171
+ return [true, found_indexes] if found
172
+ end
173
+ end
174
+ []
175
+ end
176
+
177
+ def find_descriptor(indexes, messages)
178
+ first_index = indexes.shift
179
+ message = messages[first_index]
180
+ path = [message.name]
181
+ while indexes.length.positive?
182
+ message = message.nested_type[indexes.shift]
183
+ path.push(message.name)
184
+ end
185
+ path
186
+ end
187
+
149
188
  # Write an int with zig-zag encoding. Copied from Avro.
150
189
  def write_int(stream, n)
151
190
  n = (n << 1) ^ (n >> 63)
@@ -169,7 +208,7 @@ class ProtoTurf
169
208
  (n >> 1) ^ -(n & 1)
170
209
  end
171
210
 
172
- def decode_protobuf(schema, encoded)
211
+ def decode_protobuf(schema, encoded, indexes)
173
212
  # get the package
174
213
  package = schema.match(/package (\S+);/)[1]
175
214
  # get the first message in the protobuf text
@@ -181,7 +220,9 @@ class ProtoTurf
181
220
  unless descriptor
182
221
  raise "Could not find schema for #{full_name}. Make sure the corresponding .proto file has been compiled and loaded."
183
222
  end
184
- descriptor.msgclass.decode(encoded)
223
+ path = find_descriptor(indexes, descriptor.file_descriptor.to_proto.message_type)
224
+ correct_message = Google::Protobuf::DescriptorPool.generated_pool.lookup("#{package}.#{path.join('.')}")
225
+ correct_message.msgclass.decode(encoded)
185
226
  end
186
227
 
187
228
  def register_schema(file_descriptor, subject: nil)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proto_turf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
@@ -73,6 +73,7 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - CHANGELOG.md
76
77
  - LICENSE
77
78
  - README.md
78
79
  - lib/proto_turf.rb