google-protobuf 3.25.5-aarch64-linux → 4.26.0-aarch64-linux

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.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

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