google-protobuf 3.19.1 → 4.30.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +153 -166
  4. data/ext/google/protobuf_c/convert.h +15 -37
  5. data/ext/google/protobuf_c/defs.c +867 -251
  6. data/ext/google/protobuf_c/defs.h +22 -47
  7. data/ext/google/protobuf_c/extconf.rb +25 -5
  8. data/ext/google/protobuf_c/glue.c +135 -0
  9. data/ext/google/protobuf_c/map.c +182 -145
  10. data/ext/google/protobuf_c/map.h +16 -35
  11. data/ext/google/protobuf_c/message.c +534 -437
  12. data/ext/google/protobuf_c/message.h +30 -49
  13. data/ext/google/protobuf_c/protobuf.c +125 -238
  14. data/ext/google/protobuf_c/protobuf.h +40 -49
  15. data/ext/google/protobuf_c/repeated_field.c +152 -120
  16. data/ext/google/protobuf_c/repeated_field.h +16 -34
  17. data/ext/google/protobuf_c/ruby-upb.c +15827 -7228
  18. data/ext/google/protobuf_c/ruby-upb.h +15075 -3866
  19. data/ext/google/protobuf_c/shared_convert.c +69 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +37 -0
  22. data/ext/google/protobuf_c/shared_message.h +21 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +6 -8
  30. data/lib/google/protobuf/api_pb.rb +6 -26
  31. data/lib/google/protobuf/descriptor_pb.rb +24 -225
  32. data/lib/google/protobuf/duration_pb.rb +6 -8
  33. data/lib/google/protobuf/empty_pb.rb +6 -6
  34. data/lib/google/protobuf/ffi/descriptor.rb +175 -0
  35. data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
  36. data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
  37. data/lib/google/protobuf/ffi/ffi.rb +214 -0
  38. data/lib/google/protobuf/ffi/field_descriptor.rb +340 -0
  39. data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
  40. data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
  41. data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
  42. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
  43. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  44. data/lib/google/protobuf/ffi/map.rb +433 -0
  45. data/lib/google/protobuf/ffi/message.rb +783 -0
  46. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
  50. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  51. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  52. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  53. data/lib/google/protobuf/message_exts.rb +10 -28
  54. data/lib/google/protobuf/plugin_pb.rb +25 -0
  55. data/lib/google/protobuf/repeated_field.rb +22 -33
  56. data/lib/google/protobuf/source_context_pb.rb +6 -7
  57. data/lib/google/protobuf/struct_pb.rb +6 -23
  58. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  59. data/lib/google/protobuf/type_pb.rb +6 -71
  60. data/lib/google/protobuf/well_known_types.rb +16 -40
  61. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  62. data/lib/google/protobuf.rb +32 -50
  63. data/lib/google/protobuf_ffi.rb +52 -0
  64. data/lib/google/protobuf_native.rb +19 -0
  65. data/lib/google/tasks/ffi.rake +100 -0
  66. metadata +97 -20
  67. data/lib/google/protobuf/descriptor_dsl.rb +0 -458
  68. data/tests/basic.rb +0 -640
  69. data/tests/generated_code_test.rb +0 -23
  70. data/tests/stress.rb +0 -38
@@ -1,458 +0,0 @@
1
- #!/usr/bin/ruby
2
- #
3
- # Code that implements the DSL for defining proto messages.
4
-
5
- require 'google/protobuf/descriptor_pb'
6
-
7
- module Google
8
- module Protobuf
9
- module Internal
10
- class AtomicCounter
11
- def initialize
12
- @n = 0
13
- @mu = Mutex.new
14
- end
15
-
16
- def get_and_increment
17
- n = @n
18
- @mu.synchronize {
19
- @n += 1
20
- }
21
- return n
22
- end
23
- end
24
-
25
- class Builder
26
- @@file_number = AtomicCounter.new
27
-
28
- def initialize(pool)
29
- @pool = pool
30
- @default_file = nil # Constructed lazily
31
- end
32
-
33
- def add_file(name, options={}, &block)
34
- builder = FileBuilder.new(@pool, name, options)
35
- builder.instance_eval(&block)
36
- internal_add_file(builder)
37
- end
38
-
39
- def add_message(name, &block)
40
- internal_default_file.add_message(name, &block)
41
- end
42
-
43
- def add_enum(name, &block)
44
- internal_default_file.add_enum(name, &block)
45
- end
46
-
47
- # ---- Internal methods, not part of the DSL ----
48
-
49
- def build
50
- if @default_file
51
- internal_add_file(@default_file)
52
- end
53
- end
54
-
55
- private def internal_add_file(file_builder)
56
- proto = file_builder.build
57
- serialized = Google::Protobuf::FileDescriptorProto.encode(proto)
58
- @pool.add_serialized_file(serialized)
59
- end
60
-
61
- private def internal_default_file
62
- number = @@file_number.get_and_increment
63
- filename = "ruby_default_file#{number}.proto"
64
- @default_file ||= FileBuilder.new(@pool, filename)
65
- end
66
- end
67
-
68
- class FileBuilder
69
- def initialize(pool, name, options={})
70
- @pool = pool
71
- @file_proto = Google::Protobuf::FileDescriptorProto.new(
72
- name: name,
73
- syntax: options.fetch(:syntax, "proto3")
74
- )
75
- end
76
-
77
- def add_message(name, &block)
78
- builder = MessageBuilder.new(name, self, @file_proto)
79
- builder.instance_eval(&block)
80
- builder.internal_add_synthetic_oneofs
81
- end
82
-
83
- def add_enum(name, &block)
84
- EnumBuilder.new(name, @file_proto).instance_eval(&block)
85
- end
86
-
87
- # ---- Internal methods, not part of the DSL ----
88
-
89
- # These methods fix up the file descriptor to account for differences
90
- # between the DSL and FileDescriptorProto.
91
-
92
- # The DSL can omit a package name; here we infer what the package is if
93
- # was not specified.
94
- def infer_package(names)
95
- # Package is longest common prefix ending in '.', if any.
96
- if not names.empty?
97
- min, max = names.minmax
98
- last_common_dot = nil
99
- min.size.times { |i|
100
- if min[i] != max[i] then break end
101
- if min[i] == "." then last_common_dot = i end
102
- }
103
- if last_common_dot
104
- return min.slice(0, last_common_dot)
105
- end
106
- end
107
-
108
- nil
109
- end
110
-
111
- def rewrite_enum_default(field)
112
- if field.type != :TYPE_ENUM or !field.has_default_value? or !field.has_type_name?
113
- return
114
- end
115
-
116
- value = field.default_value
117
- type_name = field.type_name
118
-
119
- if value.empty? or value[0].ord < "0".ord or value[0].ord > "9".ord
120
- return
121
- end
122
-
123
- if type_name.empty? || type_name[0] != "."
124
- return
125
- end
126
-
127
- type_name = type_name[1..-1]
128
- as_int = Integer(value) rescue return
129
-
130
- enum_desc = @pool.lookup(type_name)
131
- if enum_desc.is_a?(Google::Protobuf::EnumDescriptor)
132
- # Enum was defined in a previous file.
133
- name = enum_desc.lookup_value(as_int)
134
- if name
135
- # Update the default value in the proto.
136
- field.default_value = name
137
- end
138
- else
139
- # See if enum was defined in this file.
140
- @file_proto.enum_type.each { |enum_proto|
141
- if enum_proto.name == type_name
142
- enum_proto.value.each { |enum_value_proto|
143
- if enum_value_proto.number == as_int
144
- # Update the default value in the proto.
145
- field.default_value = enum_value_proto.name
146
- return
147
- end
148
- }
149
- # We found the right enum, but no value matched.
150
- return
151
- end
152
- }
153
- end
154
- end
155
-
156
- # Historically we allowed enum defaults to be specified as a number.
157
- # In retrospect this was a mistake as descriptors require defaults to
158
- # be specified as a label. This can make a difference if multiple
159
- # labels have the same number.
160
- #
161
- # Here we do a pass over all enum defaults and rewrite numeric defaults
162
- # by looking up their labels. This is complicated by the fact that the
163
- # enum definition can live in either the symtab or the file_proto.
164
- #
165
- # We take advantage of the fact that this is called *before* enums or
166
- # messages are nested in other messages, so we only have to iterate
167
- # one level deep.
168
- def rewrite_enum_defaults
169
- @file_proto.message_type.each { |msg|
170
- msg.field.each { |field|
171
- rewrite_enum_default(field)
172
- }
173
- }
174
- end
175
-
176
- # We have to do some relatively complicated logic here for backward
177
- # compatibility.
178
- #
179
- # In descriptor.proto, messages are nested inside other messages if that is
180
- # what the original .proto file looks like. For example, suppose we have this
181
- # foo.proto:
182
- #
183
- # package foo;
184
- # message Bar {
185
- # message Baz {}
186
- # }
187
- #
188
- # The descriptor for this must look like this:
189
- #
190
- # file {
191
- # name: "test.proto"
192
- # package: "foo"
193
- # message_type {
194
- # name: "Bar"
195
- # nested_type {
196
- # name: "Baz"
197
- # }
198
- # }
199
- # }
200
- #
201
- # However, the Ruby generated code has always generated messages in a flat,
202
- # non-nested way:
203
- #
204
- # Google::Protobuf::DescriptorPool.generated_pool.build do
205
- # add_message "foo.Bar" do
206
- # end
207
- # add_message "foo.Bar.Baz" do
208
- # end
209
- # end
210
- #
211
- # Here we need to do a translation where we turn this generated code into the
212
- # above descriptor. We need to infer that "foo" is the package name, and not
213
- # a message itself. */
214
-
215
- def split_parent_name(msg_or_enum)
216
- name = msg_or_enum.name
217
- idx = name.rindex(?.)
218
- if idx
219
- return name[0...idx], name[idx+1..-1]
220
- else
221
- return nil, name
222
- end
223
- end
224
-
225
- def get_parent_msg(msgs_by_name, name, parent_name)
226
- parent_msg = msgs_by_name[parent_name]
227
- if parent_msg.nil?
228
- raise "To define name #{name}, there must be a message named #{parent_name} to enclose it"
229
- end
230
- return parent_msg
231
- end
232
-
233
- def fix_nesting
234
- # Calculate and update package.
235
- msgs_by_name = @file_proto.message_type.map { |msg| [msg.name, msg] }.to_h
236
- enum_names = @file_proto.enum_type.map { |enum_proto| enum_proto.name }
237
-
238
- package = infer_package(msgs_by_name.keys + enum_names)
239
- if package
240
- @file_proto.package = package
241
- end
242
-
243
- # Update nesting based on package.
244
- final_msgs = Google::Protobuf::RepeatedField.new(:message, Google::Protobuf::DescriptorProto)
245
- final_enums = Google::Protobuf::RepeatedField.new(:message, Google::Protobuf::EnumDescriptorProto)
246
-
247
- # Note: We don't iterate over msgs_by_name.values because we want to
248
- # preserve order as listed in the DSL.
249
- @file_proto.message_type.each { |msg|
250
- parent_name, msg.name = split_parent_name(msg)
251
- if parent_name == package
252
- final_msgs << msg
253
- else
254
- get_parent_msg(msgs_by_name, msg.name, parent_name).nested_type << msg
255
- end
256
- }
257
-
258
- @file_proto.enum_type.each { |enum|
259
- parent_name, enum.name = split_parent_name(enum)
260
- if parent_name == package
261
- final_enums << enum
262
- else
263
- get_parent_msg(msgs_by_name, enum.name, parent_name).enum_type << enum
264
- end
265
- }
266
-
267
- @file_proto.message_type = final_msgs
268
- @file_proto.enum_type = final_enums
269
- end
270
-
271
- def internal_file_proto
272
- @file_proto
273
- end
274
-
275
- def build
276
- rewrite_enum_defaults
277
- fix_nesting
278
- return @file_proto
279
- end
280
- end
281
-
282
- class MessageBuilder
283
- def initialize(name, file_builder, file_proto)
284
- @file_builder = file_builder
285
- @msg_proto = Google::Protobuf::DescriptorProto.new(
286
- :name => name
287
- )
288
- file_proto.message_type << @msg_proto
289
- end
290
-
291
- def optional(name, type, number, type_class=nil, options=nil)
292
- internal_add_field(:LABEL_OPTIONAL, name, type, number, type_class, options)
293
- end
294
-
295
- def proto3_optional(name, type, number, type_class=nil, options=nil)
296
- internal_add_field(:LABEL_OPTIONAL, name, type, number, type_class, options,
297
- proto3_optional: true)
298
- end
299
-
300
- def required(name, type, number, type_class=nil, options=nil)
301
- internal_add_field(:LABEL_REQUIRED, name, type, number, type_class, options)
302
- end
303
-
304
- def repeated(name, type, number, type_class = nil, options=nil)
305
- internal_add_field(:LABEL_REPEATED, name, type, number, type_class, options)
306
- end
307
-
308
- def oneof(name, &block)
309
- OneofBuilder.new(name, self).instance_eval(&block)
310
- end
311
-
312
- # Defines a new map field on this message type with the given key and
313
- # value types, tag number, and type class (for message and enum value
314
- # types). The key type must be :int32/:uint32/:int64/:uint64, :bool, or
315
- # :string. The value type type must be a Ruby symbol (as accepted by
316
- # FieldDescriptor#type=) and the type_class must be a string, if
317
- # present (as accepted by FieldDescriptor#submsg_name=).
318
- def map(name, key_type, value_type, number, value_type_class = nil)
319
- if key_type == :float or key_type == :double or key_type == :enum or
320
- key_type == :message
321
- raise ArgError, "Not an acceptable key type: " + key_type
322
- end
323
- entry_name = "#{@msg_proto.name}_MapEntry_#{name}"
324
-
325
- @file_builder.add_message entry_name do
326
- optional :key, key_type, 1
327
- optional :value, value_type, 2, value_type_class
328
- end
329
- options = @file_builder.internal_file_proto.message_type.last.options ||= MessageOptions.new
330
- options.map_entry = true
331
- repeated name, :message, number, entry_name
332
- end
333
-
334
- # ---- Internal methods, not part of the DSL ----
335
-
336
- def internal_add_synthetic_oneofs
337
- # We have to build a set of all names, to ensure that synthetic oneofs
338
- # are not creating conflicts
339
- names = {}
340
- @msg_proto.field.each { |field| names[field.name] = true }
341
- @msg_proto.oneof_decl.each { |oneof| names[oneof.name] = true }
342
-
343
- @msg_proto.field.each { |field|
344
- if field.proto3_optional
345
- # Prepend '_' until we are no longer conflicting.
346
- oneof_name = field.name
347
- while names[oneof_name]
348
- oneof_name = "_" + oneof_name
349
- end
350
- names[oneof_name] = true
351
- field.oneof_index = @msg_proto.oneof_decl.size
352
- @msg_proto.oneof_decl << Google::Protobuf::OneofDescriptorProto.new(
353
- name: oneof_name
354
- )
355
- end
356
- }
357
- end
358
-
359
- def internal_add_field(label, name, type, number, type_class, options,
360
- oneof_index: nil, proto3_optional: false)
361
- # Allow passing either:
362
- # - (name, type, number, options) or
363
- # - (name, type, number, type_class, options)
364
- if options.nil? and type_class.instance_of?(Hash)
365
- options = type_class;
366
- type_class = nil;
367
- end
368
-
369
- field_proto = Google::Protobuf::FieldDescriptorProto.new(
370
- :label => label,
371
- :name => name,
372
- :type => ("TYPE_" + type.to_s.upcase).to_sym,
373
- :number => number
374
- )
375
-
376
- if type_class
377
- # Make it an absolute type name by prepending a dot.
378
- field_proto.type_name = "." + type_class
379
- end
380
-
381
- if oneof_index
382
- field_proto.oneof_index = oneof_index
383
- end
384
-
385
- if proto3_optional
386
- field_proto.proto3_optional = true
387
- end
388
-
389
- if options
390
- if options.key?(:default)
391
- default = options[:default]
392
- if !default.instance_of?(String)
393
- # Call #to_s since all defaults are strings in the descriptor.
394
- default = default.to_s
395
- end
396
- # XXX: we should be C-escaping bytes defaults.
397
- field_proto.default_value = default.dup.force_encoding("UTF-8")
398
- end
399
- if options.key?(:json_name)
400
- field_proto.json_name = options[:json_name]
401
- end
402
- end
403
-
404
- @msg_proto.field << field_proto
405
- end
406
-
407
- def internal_msg_proto
408
- @msg_proto
409
- end
410
- end
411
-
412
- class OneofBuilder
413
- def initialize(name, msg_builder)
414
- @msg_builder = msg_builder
415
- oneof_proto = Google::Protobuf::OneofDescriptorProto.new(
416
- :name => name
417
- )
418
- msg_proto = msg_builder.internal_msg_proto
419
- @oneof_index = msg_proto.oneof_decl.size
420
- msg_proto.oneof_decl << oneof_proto
421
- end
422
-
423
- def optional(name, type, number, type_class=nil, options=nil)
424
- @msg_builder.internal_add_field(
425
- :LABEL_OPTIONAL, name, type, number, type_class, options,
426
- oneof_index: @oneof_index)
427
- end
428
- end
429
-
430
- class EnumBuilder
431
- def initialize(name, file_proto)
432
- @enum_proto = Google::Protobuf::EnumDescriptorProto.new(
433
- :name => name
434
- )
435
- file_proto.enum_type << @enum_proto
436
- end
437
-
438
- def value(name, number)
439
- enum_value_proto = Google::Protobuf::EnumValueDescriptorProto.new(
440
- name: name,
441
- number: number
442
- )
443
- @enum_proto.value << enum_value_proto
444
- end
445
- end
446
-
447
- end
448
-
449
- # Re-open the class (the rest of the class is implemented in C)
450
- class DescriptorPool
451
- def build(&block)
452
- builder = Internal::Builder.new(self)
453
- builder.instance_eval(&block)
454
- builder.build
455
- end
456
- end
457
- end
458
- end