google-protobuf 3.25.2-arm64-darwin → 4.26.0-arm64-darwin
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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +7 -4
- data/ext/google/protobuf_c/defs.c +40 -27
- data/ext/google/protobuf_c/extconf.rb +1 -1
- data/ext/google/protobuf_c/map.c +12 -19
- data/ext/google/protobuf_c/map.h +1 -1
- data/ext/google/protobuf_c/message.c +41 -77
- data/ext/google/protobuf_c/message.h +1 -1
- data/ext/google/protobuf_c/protobuf.c +19 -6
- data/ext/google/protobuf_c/repeated_field.c +6 -15
- data/ext/google/protobuf_c/repeated_field.h +1 -1
- data/ext/google/protobuf_c/ruby-upb.c +11788 -10795
- data/ext/google/protobuf_c/ruby-upb.h +5164 -4242
- data/ext/google/protobuf_c/shared_convert.c +5 -3
- data/ext/google/protobuf_c/shared_convert.h +2 -2
- data/ext/google/protobuf_c/shared_message.c +8 -6
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
- data/lib/google/2.7/protobuf_c.bundle +0 -0
- data/lib/google/3.0/protobuf_c.bundle +0 -0
- data/lib/google/3.1/protobuf_c.bundle +0 -0
- data/lib/google/3.2/protobuf_c.bundle +0 -0
- data/lib/google/3.3/protobuf_c.bundle +0 -0
- data/lib/google/protobuf/any_pb.rb +1 -22
- data/lib/google/protobuf/api_pb.rb +1 -24
- data/lib/google/protobuf/descriptor_pb.rb +2 -23
- data/lib/google/protobuf/duration_pb.rb +1 -22
- data/lib/google/protobuf/empty_pb.rb +1 -22
- data/lib/google/protobuf/ffi/descriptor.rb +2 -3
- data/lib/google/protobuf/ffi/enum_descriptor.rb +1 -1
- data/lib/google/protobuf/ffi/ffi.rb +3 -1
- data/lib/google/protobuf/ffi/field_descriptor.rb +10 -1
- data/lib/google/protobuf/ffi/file_descriptor.rb +1 -13
- data/lib/google/protobuf/ffi/internal/convert.rb +7 -23
- data/lib/google/protobuf/ffi/map.rb +13 -11
- data/lib/google/protobuf/ffi/message.rb +10 -13
- data/lib/google/protobuf/ffi/object_cache.rb +3 -3
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +1 -1
- data/lib/google/protobuf/ffi/repeated_field.rb +12 -10
- data/lib/google/protobuf/field_mask_pb.rb +1 -22
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/plugin_pb.rb +2 -24
- data/lib/google/protobuf/repeated_field.rb +1 -2
- data/lib/google/protobuf/source_context_pb.rb +1 -22
- data/lib/google/protobuf/struct_pb.rb +1 -22
- data/lib/google/protobuf/timestamp_pb.rb +1 -22
- data/lib/google/protobuf/type_pb.rb +1 -24
- data/lib/google/protobuf/wrappers_pb.rb +1 -22
- data/lib/google/protobuf.rb +1 -1
- data/lib/google/protobuf_ffi.rb +1 -2
- data/lib/google/protobuf_native.rb +0 -1
- data/lib/google/tasks/ffi.rake +1 -3
- metadata +10 -12
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
- data/lib/google/protobuf/descriptor_dsl.rb +0 -465
- 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
|