google-protobuf 3.14.0 → 3.15.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: 4efa381bee3e947252b6df3d7e26ab4163892b419131e6995d599b91da9eb069
4
- data.tar.gz: 45267244b3e9c99d5cb27aac3727f8739c6e7ad1e0097a6f0c9204aaebddb609
3
+ metadata.gz: adbba3c7159278b9926b5dbf75a5d76030695ae716122593d756b12d4e30f70d
4
+ data.tar.gz: ea8bc4279e712286fa3d3a18649f847a0717031c5295f261a2f7846dfb9e5c69
5
5
  SHA512:
6
- metadata.gz: ff369fc09844a202a30aaf129bcd141d5e3c576c7870f8fc202c3bf4792cd427b4515ebacd9557c2056a613832bcd425156f18d17fe40887df1b09c39146e5ec
7
- data.tar.gz: 6743af82db871d76712e06fb8b6571b61ce4e4c520191243eed922f382b9a50d7938dfbd074a0faa9369a8ed8362b89c8fe3d80e1595166f63e01fe297ae7e24
6
+ metadata.gz: 3f5c170a07539388568608d9e97285ed1985057cb342c5a63a8e827e6946b0bc1d446ebdd27aba08d11ded7813a93bb0bebc5205122226ea2b8dcd6cb4fba7d0
7
+ data.tar.gz: '084b27c355258972a8f2b1a839d3580a93d45bfd564730d1afebd50ae2238ef6e00035557f6545f6fcd33f9ef4ab1690aa8e0ade9ecdccf2028991dab6b8cb3c'
@@ -0,0 +1,349 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2008 Google Inc. All rights reserved.
3
+ // https://developers.google.com/protocol-buffers/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ // -----------------------------------------------------------------------------
32
+ // Ruby <-> upb data conversion functions.
33
+ //
34
+ // This file Also contains a few other assorted algorithms on upb_msgval.
35
+ //
36
+ // None of the algorithms in this file require any access to the internal
37
+ // representation of Ruby or upb objects.
38
+ // -----------------------------------------------------------------------------
39
+
40
+ #include "convert.h"
41
+
42
+ #include "message.h"
43
+ #include "protobuf.h"
44
+ #include "third_party/wyhash/wyhash.h"
45
+
46
+ static upb_strview Convert_StringData(VALUE str, upb_arena *arena) {
47
+ upb_strview ret;
48
+ if (arena) {
49
+ char *ptr = upb_arena_malloc(arena, RSTRING_LEN(str));
50
+ memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str));
51
+ ret.data = ptr;
52
+ } else {
53
+ // Data is only needed temporarily (within map lookup).
54
+ ret.data = RSTRING_PTR(str);
55
+ }
56
+ ret.size = RSTRING_LEN(str);
57
+ return ret;
58
+ }
59
+
60
+ static bool is_ruby_num(VALUE value) {
61
+ return (TYPE(value) == T_FLOAT ||
62
+ TYPE(value) == T_FIXNUM ||
63
+ TYPE(value) == T_BIGNUM);
64
+ }
65
+
66
+ static void Convert_CheckInt(const char* name, upb_fieldtype_t type,
67
+ VALUE val) {
68
+ if (!is_ruby_num(val)) {
69
+ rb_raise(cTypeError,
70
+ "Expected number type for integral field '%s' (given %s).", name,
71
+ rb_class2name(CLASS_OF(val)));
72
+ }
73
+
74
+ // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
75
+ // bound; we just need to do precision checks (i.e., disallow rounding) and
76
+ // check for < 0 on unsigned types.
77
+ if (TYPE(val) == T_FLOAT) {
78
+ double dbl_val = NUM2DBL(val);
79
+ if (floor(dbl_val) != dbl_val) {
80
+ rb_raise(rb_eRangeError,
81
+ "Non-integral floating point value assigned to integer field "
82
+ "'%s' (given %s).",
83
+ name, rb_class2name(CLASS_OF(val)));
84
+ }
85
+ }
86
+ if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
87
+ if (NUM2DBL(val) < 0) {
88
+ rb_raise(
89
+ rb_eRangeError,
90
+ "Assigning negative value to unsigned integer field '%s' (given %s).",
91
+ name, rb_class2name(CLASS_OF(val)));
92
+ }
93
+ }
94
+ }
95
+
96
+ static int32_t Convert_ToEnum(VALUE value, const char* name,
97
+ const upb_enumdef* e) {
98
+ int32_t val;
99
+
100
+ switch (TYPE(value)) {
101
+ case T_FLOAT:
102
+ case T_FIXNUM:
103
+ case T_BIGNUM:
104
+ Convert_CheckInt(name, UPB_TYPE_INT32, value);
105
+ val = NUM2INT(value);
106
+ break;
107
+ case T_STRING:
108
+ if (!upb_enumdef_ntoi(e, RSTRING_PTR(value), RSTRING_LEN(value), &val)) {
109
+ goto unknownval;
110
+ }
111
+ break;
112
+ case T_SYMBOL:
113
+ if (!upb_enumdef_ntoiz(e, rb_id2name(SYM2ID(value)), &val)) {
114
+ goto unknownval;
115
+ }
116
+ break;
117
+ default:
118
+ rb_raise(cTypeError,
119
+ "Expected number or symbol type for enum field '%s'.", name);
120
+ }
121
+
122
+ return val;
123
+
124
+ unknownval:
125
+ rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
126
+ }
127
+
128
+ upb_msgval Convert_RubyToUpb(VALUE value, const char* name, TypeInfo type_info,
129
+ upb_arena* arena) {
130
+ upb_msgval ret;
131
+
132
+ switch (type_info.type) {
133
+ case UPB_TYPE_FLOAT:
134
+ if (!is_ruby_num(value)) {
135
+ rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
136
+ name, rb_class2name(CLASS_OF(value)));
137
+ }
138
+ ret.float_val = NUM2DBL(value);
139
+ break;
140
+ case UPB_TYPE_DOUBLE:
141
+ if (!is_ruby_num(value)) {
142
+ rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
143
+ name, rb_class2name(CLASS_OF(value)));
144
+ }
145
+ ret.double_val = NUM2DBL(value);
146
+ break;
147
+ case UPB_TYPE_BOOL: {
148
+ if (value == Qtrue) {
149
+ ret.bool_val = 1;
150
+ } else if (value == Qfalse) {
151
+ ret.bool_val = 0;
152
+ } else {
153
+ rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
154
+ name, rb_class2name(CLASS_OF(value)));
155
+ }
156
+ break;
157
+ }
158
+ case UPB_TYPE_STRING: {
159
+ VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding());
160
+ if (CLASS_OF(value) == rb_cSymbol) {
161
+ value = rb_funcall(value, rb_intern("to_s"), 0);
162
+ } else if (CLASS_OF(value) != rb_cString) {
163
+ rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
164
+ name, rb_class2name(CLASS_OF(value)));
165
+ }
166
+
167
+ if (rb_obj_encoding(value) != utf8) {
168
+ // Note: this will not duplicate underlying string data unless necessary.
169
+ value = rb_str_encode(value, utf8, 0, Qnil);
170
+
171
+ if (rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
172
+ rb_raise(rb_eEncodingError, "String is invalid UTF-8");
173
+ }
174
+ }
175
+
176
+ ret.str_val = Convert_StringData(value, arena);
177
+ break;
178
+ }
179
+ case UPB_TYPE_BYTES: {
180
+ VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding());
181
+ if (CLASS_OF(value) != rb_cString) {
182
+ rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
183
+ name, rb_class2name(CLASS_OF(value)));
184
+ }
185
+
186
+ if (rb_obj_encoding(value) != bytes) {
187
+ // Note: this will not duplicate underlying string data unless necessary.
188
+ // TODO(haberman): is this really necessary to get raw bytes?
189
+ value = rb_str_encode(value, bytes, 0, Qnil);
190
+ }
191
+
192
+ ret.str_val = Convert_StringData(value, arena);
193
+ break;
194
+ }
195
+ case UPB_TYPE_MESSAGE:
196
+ ret.msg_val =
197
+ Message_GetUpbMessage(value, type_info.def.msgdef, name, arena);
198
+ break;
199
+ case UPB_TYPE_ENUM:
200
+ ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef);
201
+ break;
202
+ case UPB_TYPE_INT32:
203
+ case UPB_TYPE_INT64:
204
+ case UPB_TYPE_UINT32:
205
+ case UPB_TYPE_UINT64:
206
+ Convert_CheckInt(name, type_info.type, value);
207
+ switch (type_info.type) {
208
+ case UPB_TYPE_INT32:
209
+ ret.int32_val = NUM2INT(value);
210
+ break;
211
+ case UPB_TYPE_INT64:
212
+ ret.int64_val = NUM2LL(value);
213
+ break;
214
+ case UPB_TYPE_UINT32:
215
+ ret.uint32_val = NUM2UINT(value);
216
+ break;
217
+ case UPB_TYPE_UINT64:
218
+ ret.uint64_val = NUM2ULL(value);
219
+ break;
220
+ default:
221
+ break;
222
+ }
223
+ break;
224
+ default:
225
+ break;
226
+ }
227
+
228
+ return ret;
229
+ }
230
+
231
+ VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena) {
232
+ switch (type_info.type) {
233
+ case UPB_TYPE_FLOAT:
234
+ return DBL2NUM(upb_val.float_val);
235
+ case UPB_TYPE_DOUBLE:
236
+ return DBL2NUM(upb_val.double_val);
237
+ case UPB_TYPE_BOOL:
238
+ return upb_val.bool_val ? Qtrue : Qfalse;
239
+ case UPB_TYPE_INT32:
240
+ return INT2NUM(upb_val.int32_val);
241
+ case UPB_TYPE_INT64:
242
+ return LL2NUM(upb_val.int64_val);
243
+ case UPB_TYPE_UINT32:
244
+ return UINT2NUM(upb_val.uint32_val);
245
+ case UPB_TYPE_UINT64:
246
+ return ULL2NUM(upb_val.int64_val);
247
+ case UPB_TYPE_ENUM: {
248
+ const char* name =
249
+ upb_enumdef_iton(type_info.def.enumdef, upb_val.int32_val);
250
+ if (name) {
251
+ return ID2SYM(rb_intern(name));
252
+ } else {
253
+ return INT2NUM(upb_val.int32_val);
254
+ }
255
+ }
256
+ case UPB_TYPE_STRING: {
257
+ VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size);
258
+ rb_enc_associate(str_rb, rb_utf8_encoding());
259
+ rb_obj_freeze(str_rb);
260
+ return str_rb;
261
+ }
262
+ case UPB_TYPE_BYTES: {
263
+ VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size);
264
+ rb_enc_associate(str_rb, rb_ascii8bit_encoding());
265
+ rb_obj_freeze(str_rb);
266
+ return str_rb;
267
+ }
268
+ case UPB_TYPE_MESSAGE:
269
+ return Message_GetRubyWrapper((upb_msg*)upb_val.msg_val,
270
+ type_info.def.msgdef, arena);
271
+ default:
272
+ rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d",
273
+ (int)type_info.type);
274
+ }
275
+ }
276
+
277
+ upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info,
278
+ upb_arena* arena) {
279
+ upb_msgval new_msgval;
280
+
281
+ switch (type_info.type) {
282
+ default:
283
+ memcpy(&new_msgval, &msgval, sizeof(msgval));
284
+ break;
285
+ case UPB_TYPE_STRING:
286
+ case UPB_TYPE_BYTES: {
287
+ size_t n = msgval.str_val.size;
288
+ char *mem = upb_arena_malloc(arena, n);
289
+ new_msgval.str_val.data = mem;
290
+ new_msgval.str_val.size = n;
291
+ memcpy(mem, msgval.str_val.data, n);
292
+ break;
293
+ }
294
+ case UPB_TYPE_MESSAGE:
295
+ new_msgval.msg_val =
296
+ Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena);
297
+ break;
298
+ }
299
+
300
+ return new_msgval;
301
+ }
302
+
303
+ bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info) {
304
+ switch (type_info.type) {
305
+ case UPB_TYPE_BOOL:
306
+ return memcmp(&val1, &val2, 1) == 0;
307
+ case UPB_TYPE_FLOAT:
308
+ case UPB_TYPE_INT32:
309
+ case UPB_TYPE_UINT32:
310
+ case UPB_TYPE_ENUM:
311
+ return memcmp(&val1, &val2, 4) == 0;
312
+ case UPB_TYPE_DOUBLE:
313
+ case UPB_TYPE_INT64:
314
+ case UPB_TYPE_UINT64:
315
+ return memcmp(&val1, &val2, 8) == 0;
316
+ case UPB_TYPE_STRING:
317
+ case UPB_TYPE_BYTES:
318
+ return val1.str_val.size != val2.str_val.size ||
319
+ memcmp(val1.str_val.data, val2.str_val.data,
320
+ val1.str_val.size) == 0;
321
+ case UPB_TYPE_MESSAGE:
322
+ return Message_Equal(val1.msg_val, val2.msg_val, type_info.def.msgdef);
323
+ default:
324
+ rb_raise(rb_eRuntimeError, "Internal error, unexpected type");
325
+ }
326
+ }
327
+
328
+ uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed) {
329
+ switch (type_info.type) {
330
+ case UPB_TYPE_BOOL:
331
+ return wyhash(&val, 1, seed, _wyp);
332
+ case UPB_TYPE_FLOAT:
333
+ case UPB_TYPE_INT32:
334
+ case UPB_TYPE_UINT32:
335
+ case UPB_TYPE_ENUM:
336
+ return wyhash(&val, 4, seed, _wyp);
337
+ case UPB_TYPE_DOUBLE:
338
+ case UPB_TYPE_INT64:
339
+ case UPB_TYPE_UINT64:
340
+ return wyhash(&val, 8, seed, _wyp);
341
+ case UPB_TYPE_STRING:
342
+ case UPB_TYPE_BYTES:
343
+ return wyhash(val.str_val.data, val.str_val.size, seed, _wyp);
344
+ case UPB_TYPE_MESSAGE:
345
+ return Message_Hash(val.msg_val, type_info.def.msgdef, seed);
346
+ default:
347
+ rb_raise(rb_eRuntimeError, "Internal error, unexpected type");
348
+ }
349
+ }
@@ -0,0 +1,72 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2008 Google Inc. All rights reserved.
3
+ // https://developers.google.com/protocol-buffers/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright
10
+ // notice, this list of conditions and the following disclaimer.
11
+ // * Redistributions in binary form must reproduce the above
12
+ // copyright notice, this list of conditions and the following disclaimer
13
+ // in the documentation and/or other materials provided with the
14
+ // distribution.
15
+ // * Neither the name of Google Inc. nor the names of its
16
+ // contributors may be used to endorse or promote products derived from
17
+ // this software without specific prior written permission.
18
+ //
19
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ #ifndef RUBY_PROTOBUF_CONVERT_H_
32
+ #define RUBY_PROTOBUF_CONVERT_H_
33
+
34
+ #include <ruby/ruby.h>
35
+
36
+ #include "protobuf.h"
37
+ #include "ruby-upb.h"
38
+
39
+ // Converts |ruby_val| to a upb_msgval according to |type_info|.
40
+ //
41
+ // The |arena| parameter indicates the lifetime of the container where this
42
+ // value will be assigned. It is used as follows:
43
+ // - If type is string or bytes, the string data will be copied into |arena|.
44
+ // - If type is message, and we need to auto-construct a message due to implicit
45
+ // conversions (eg. Time -> Google::Protobuf::Timestamp), the new message
46
+ // will be created in |arena|.
47
+ // - If type is message and the Ruby value is a message instance, we will fuse
48
+ // the message's arena into |arena|, to ensure that this message outlives the
49
+ // container.
50
+ upb_msgval Convert_RubyToUpb(VALUE ruby_val, const char *name,
51
+ TypeInfo type_info, upb_arena *arena);
52
+
53
+ // Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve
54
+ // creating a Ruby wrapper object.
55
+ //
56
+ // The |arena| parameter indicates the arena that owns the lifetime of
57
+ // |upb_val|. Any Ruby wrapper object that is created will reference |arena|
58
+ // and ensure it outlives the wrapper.
59
+ VALUE Convert_UpbToRuby(upb_msgval upb_val, TypeInfo type_info, VALUE arena);
60
+
61
+ // Creates a deep copy of |msgval| in |arena|.
62
+ upb_msgval Msgval_DeepCopy(upb_msgval msgval, TypeInfo type_info,
63
+ upb_arena *arena);
64
+
65
+ // Returns true if |val1| and |val2| are equal. Their type is given by
66
+ // |type_info|.
67
+ bool Msgval_IsEqual(upb_msgval val1, upb_msgval val2, TypeInfo type_info);
68
+
69
+ // Returns a hash value for the given upb_msgval.
70
+ uint64_t Msgval_GetHash(upb_msgval val, TypeInfo type_info, uint64_t seed);
71
+
72
+ #endif // RUBY_PROTOBUF_CONVERT_H_
@@ -30,8 +30,35 @@
30
30
 
31
31
  #include <ctype.h>
32
32
  #include <errno.h>
33
+ #include <ruby/version.h>
34
+
35
+ #include "convert.h"
36
+ #include "message.h"
33
37
  #include "protobuf.h"
34
38
 
39
+ static VALUE Builder_build(VALUE _self);
40
+
41
+ static VALUE cMessageBuilderContext;
42
+ static VALUE cOneofBuilderContext;
43
+ static VALUE cEnumBuilderContext;
44
+ static VALUE cBuilder;
45
+
46
+ // -----------------------------------------------------------------------------
47
+ // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
48
+ // instances.
49
+ // -----------------------------------------------------------------------------
50
+
51
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def);
52
+ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def);
53
+ static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def);
54
+ static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def);
55
+ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def);
56
+
57
+ // A distinct object that is not accessible from Ruby. We use this as a
58
+ // constructor argument to enforce that certain objects cannot be created from
59
+ // Ruby.
60
+ VALUE c_only_cookie = Qnil;
61
+
35
62
  // -----------------------------------------------------------------------------
36
63
  // Common utilities.
37
64
  // -----------------------------------------------------------------------------
@@ -48,6 +75,10 @@ static VALUE rb_str_maybe_null(const char* s) {
48
75
  return rb_str_new2(s);
49
76
  }
50
77
 
78
+ // -----------------------------------------------------------------------------
79
+ // Backward compatibility code.
80
+ // -----------------------------------------------------------------------------
81
+
51
82
  static void rewrite_enum_default(const upb_symtab* symtab,
52
83
  google_protobuf_FileDescriptorProto* file,
53
84
  google_protobuf_FieldDescriptorProto* field) {
@@ -205,221 +236,70 @@ static void rewrite_nesting(VALUE msg_ent, google_protobuf_DescriptorProto* msg,
205
236
  }
206
237
  }
207
238
 
208
- /* We have to do some relatively complicated logic here for backward
209
- * compatibility.
210
- *
211
- * In descriptor.proto, messages are nested inside other messages if that is
212
- * what the original .proto file looks like. For example, suppose we have this
213
- * foo.proto:
214
- *
215
- * package foo;
216
- * message Bar {
217
- * message Baz {}
218
- * }
219
- *
220
- * The descriptor for this must look like this:
221
- *
222
- * file {
223
- * name: "test.proto"
224
- * package: "foo"
225
- * message_type {
226
- * name: "Bar"
227
- * nested_type {
228
- * name: "Baz"
229
- * }
230
- * }
231
- * }
232
- *
233
- * However, the Ruby generated code has always generated messages in a flat,
234
- * non-nested way:
235
- *
236
- * Google::Protobuf::DescriptorPool.generated_pool.build do
237
- * add_message "foo.Bar" do
238
- * end
239
- * add_message "foo.Bar.Baz" do
240
- * end
241
- * end
242
- *
243
- * Here we need to do a translation where we turn this generated code into the
244
- * above descriptor. We need to infer that "foo" is the package name, and not
245
- * a message itself.
246
- *
247
- * We delegate to Ruby to compute the transformation, for more concice and
248
- * readable code than we can do in C */
249
- static void rewrite_names(VALUE _file_builder,
250
- google_protobuf_FileDescriptorProto* file_proto) {
251
- FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
252
- upb_arena *arena = file_builder->arena;
253
- // Build params (package, msg_names, enum_names).
254
- VALUE package = Qnil;
255
- VALUE msg_names = rb_ary_new();
256
- VALUE enum_names = rb_ary_new();
257
- size_t msg_count, enum_count, i;
258
- VALUE new_package, nesting, msg_ents, enum_ents;
259
- google_protobuf_DescriptorProto** msgs;
260
- google_protobuf_EnumDescriptorProto** enums;
261
-
262
- if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
263
- upb_strview package_str =
264
- google_protobuf_FileDescriptorProto_package(file_proto);
265
- package = rb_str_new(package_str.data, package_str.size);
266
- }
267
-
268
- msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
269
- &msg_count);
270
- for (i = 0; i < msg_count; i++) {
271
- upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
272
- rb_ary_push(msg_names, rb_str_new(name.data, name.size));
273
- }
274
-
275
- enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
276
- &enum_count);
277
- for (i = 0; i < enum_count; i++) {
278
- upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
279
- rb_ary_push(enum_names, rb_str_new(name.data, name.size));
280
- }
281
-
282
- {
283
- // Call Ruby code to calculate package name and nesting.
284
- VALUE args[3] = { package, msg_names, enum_names };
285
- VALUE internal = rb_eval_string("Google::Protobuf::Internal");
286
- VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
287
-
288
- new_package = rb_ary_entry(ret, 0);
289
- nesting = rb_ary_entry(ret, 1);
290
- }
291
-
292
- // Rewrite package and names.
293
- if (new_package != Qnil) {
294
- upb_strview new_package_str =
295
- FileBuilderContext_strdup(_file_builder, new_package);
296
- google_protobuf_FileDescriptorProto_set_package(file_proto,
297
- new_package_str);
298
- }
299
-
300
- for (i = 0; i < msg_count; i++) {
301
- upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
302
- remove_path(&name);
303
- google_protobuf_DescriptorProto_set_name(msgs[i], name);
304
- }
305
-
306
- for (i = 0; i < enum_count; i++) {
307
- upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
308
- remove_path(&name);
309
- google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
310
- }
311
-
312
- // Rewrite nesting.
313
- msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
314
- enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
315
-
316
- Check_Type(msg_ents, T_ARRAY);
317
- Check_Type(enum_ents, T_ARRAY);
318
-
319
- for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
320
- VALUE msg_ent = rb_ary_entry(msg_ents, i);
321
- VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
322
- msgs[i] = msgs[NUM2INT(pos)];
323
- rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
324
- }
325
-
326
- for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
327
- VALUE enum_pos = rb_ary_entry(enum_ents, i);
328
- enums[i] = enums[NUM2INT(enum_pos)];
329
- }
330
-
331
- google_protobuf_FileDescriptorProto_resize_message_type(
332
- file_proto, RARRAY_LEN(msg_ents), arena);
333
- google_protobuf_FileDescriptorProto_resize_enum_type(
334
- file_proto, RARRAY_LEN(enum_ents), arena);
335
- }
336
-
337
239
  // -----------------------------------------------------------------------------
338
240
  // DescriptorPool.
339
241
  // -----------------------------------------------------------------------------
340
242
 
341
- #define DEFINE_CLASS(name, string_name) \
342
- VALUE c ## name = Qnil; \
343
- const rb_data_type_t _ ## name ## _type = { \
344
- string_name, \
345
- { name ## _mark, name ## _free, NULL }, \
346
- }; \
347
- name* ruby_to_ ## name(VALUE val) { \
348
- name* ret; \
349
- TypedData_Get_Struct(val, name, &_ ## name ## _type, ret); \
350
- return ret; \
351
- } \
352
-
353
- #define DEFINE_SELF(type, var, rb_var) \
354
- type* var = ruby_to_ ## type(rb_var)
243
+ typedef struct {
244
+ VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor.
245
+ upb_symtab* symtab;
246
+ } DescriptorPool;
247
+
248
+ VALUE cDescriptorPool = Qnil;
355
249
 
356
250
  // Global singleton DescriptorPool. The user is free to create others, but this
357
251
  // is used by generated code.
358
252
  VALUE generated_pool = Qnil;
359
253
 
360
- DEFINE_CLASS(DescriptorPool, "Google::Protobuf::DescriptorPool");
361
-
362
- void DescriptorPool_mark(void* _self) {
254
+ static void DescriptorPool_mark(void* _self) {
363
255
  DescriptorPool* self = _self;
364
256
  rb_gc_mark(self->def_to_descriptor);
365
257
  }
366
258
 
367
- void DescriptorPool_free(void* _self) {
259
+ static void DescriptorPool_free(void* _self) {
368
260
  DescriptorPool* self = _self;
369
-
370
261
  upb_symtab_free(self->symtab);
371
- upb_handlercache_free(self->fill_handler_cache);
372
- upb_handlercache_free(self->pb_serialize_handler_cache);
373
- upb_handlercache_free(self->json_serialize_handler_cache);
374
- upb_handlercache_free(self->json_serialize_handler_preserve_cache);
375
- upb_pbcodecache_free(self->fill_method_cache);
376
- upb_json_codecache_free(self->json_fill_method_cache);
377
-
378
262
  xfree(self);
379
263
  }
380
264
 
265
+ static const rb_data_type_t DescriptorPool_type = {
266
+ "Google::Protobuf::DescriptorPool",
267
+ {DescriptorPool_mark, DescriptorPool_free, NULL},
268
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
269
+ };
270
+
271
+ static DescriptorPool* ruby_to_DescriptorPool(VALUE val) {
272
+ DescriptorPool* ret;
273
+ TypedData_Get_Struct(val, DescriptorPool, &DescriptorPool_type, ret);
274
+ return ret;
275
+ }
276
+
277
+ // Exposed to other modules in defs.h.
278
+ const upb_symtab *DescriptorPool_GetSymtab(VALUE desc_pool_rb) {
279
+ DescriptorPool *pool = ruby_to_DescriptorPool(desc_pool_rb);
280
+ return pool->symtab;
281
+ }
282
+
381
283
  /*
382
284
  * call-seq:
383
285
  * DescriptorPool.new => pool
384
286
  *
385
287
  * Creates a new, empty, descriptor pool.
386
288
  */
387
- VALUE DescriptorPool_alloc(VALUE klass) {
289
+ static VALUE DescriptorPool_alloc(VALUE klass) {
388
290
  DescriptorPool* self = ALLOC(DescriptorPool);
389
291
  VALUE ret;
390
292
 
391
293
  self->def_to_descriptor = Qnil;
392
- ret = TypedData_Wrap_Struct(klass, &_DescriptorPool_type, self);
294
+ ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self);
393
295
 
394
296
  self->def_to_descriptor = rb_hash_new();
395
297
  self->symtab = upb_symtab_new();
396
- self->fill_handler_cache =
397
- upb_handlercache_new(add_handlers_for_message, (void*)ret);
398
- self->pb_serialize_handler_cache = upb_pb_encoder_newcache();
399
- self->json_serialize_handler_cache = upb_json_printer_newcache(false);
400
- self->json_serialize_handler_preserve_cache =
401
- upb_json_printer_newcache(true);
402
- self->fill_method_cache = upb_pbcodecache_new(self->fill_handler_cache);
403
- self->json_fill_method_cache = upb_json_codecache_new();
298
+ ObjectCache_Add(self->symtab, ret, _upb_symtab_arena(self->symtab));
404
299
 
405
300
  return ret;
406
301
  }
407
302
 
408
- void DescriptorPool_register(VALUE module) {
409
- VALUE klass = rb_define_class_under(
410
- module, "DescriptorPool", rb_cObject);
411
- rb_define_alloc_func(klass, DescriptorPool_alloc);
412
- rb_define_method(klass, "build", DescriptorPool_build, -1);
413
- rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
414
- rb_define_singleton_method(klass, "generated_pool",
415
- DescriptorPool_generated_pool, 0);
416
- rb_gc_register_address(&cDescriptorPool);
417
- cDescriptorPool = klass;
418
-
419
- rb_gc_register_address(&generated_pool);
420
- generated_pool = rb_class_new_instance(0, NULL, klass);
421
- }
422
-
423
303
  /*
424
304
  * call-seq:
425
305
  * DescriptorPool.build(&block)
@@ -430,7 +310,7 @@ void DescriptorPool_register(VALUE module) {
430
310
  * Builder#add_enum within the block as appropriate. This is the recommended,
431
311
  * idiomatic way to define new message and enum types.
432
312
  */
433
- VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
313
+ static VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
434
314
  VALUE ctx = rb_class_new_instance(1, &_self, cBuilder);
435
315
  VALUE block = rb_block_proc();
436
316
  rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
@@ -445,8 +325,8 @@ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
445
325
  * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
446
326
  * exists with the given name.
447
327
  */
448
- VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
449
- DEFINE_SELF(DescriptorPool, self, _self);
328
+ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
329
+ DescriptorPool* self = ruby_to_DescriptorPool(_self);
450
330
  const char* name_str = get_str(name);
451
331
  const upb_msgdef* msgdef;
452
332
  const upb_enumdef* enumdef;
@@ -473,31 +353,53 @@ VALUE DescriptorPool_lookup(VALUE _self, VALUE name) {
473
353
  * register types in this pool for convenience so that they do not have to hold
474
354
  * a reference to a private pool instance.
475
355
  */
476
- VALUE DescriptorPool_generated_pool(VALUE _self) {
356
+ static VALUE DescriptorPool_generated_pool(VALUE _self) {
477
357
  return generated_pool;
478
358
  }
479
359
 
360
+ static void DescriptorPool_register(VALUE module) {
361
+ VALUE klass = rb_define_class_under(
362
+ module, "DescriptorPool", rb_cObject);
363
+ rb_define_alloc_func(klass, DescriptorPool_alloc);
364
+ rb_define_method(klass, "build", DescriptorPool_build, -1);
365
+ rb_define_method(klass, "lookup", DescriptorPool_lookup, 1);
366
+ rb_define_singleton_method(klass, "generated_pool",
367
+ DescriptorPool_generated_pool, 0);
368
+ rb_gc_register_address(&cDescriptorPool);
369
+ cDescriptorPool = klass;
370
+
371
+ rb_gc_register_address(&generated_pool);
372
+ generated_pool = rb_class_new_instance(0, NULL, klass);
373
+ }
374
+
480
375
  // -----------------------------------------------------------------------------
481
376
  // Descriptor.
482
377
  // -----------------------------------------------------------------------------
483
378
 
484
- DEFINE_CLASS(Descriptor, "Google::Protobuf::Descriptor");
379
+ typedef struct {
380
+ const upb_msgdef* msgdef;
381
+ VALUE klass;
382
+ VALUE descriptor_pool;
383
+ } Descriptor;
384
+
385
+ VALUE cDescriptor = Qnil;
485
386
 
486
- void Descriptor_mark(void* _self) {
387
+ static void Descriptor_mark(void* _self) {
487
388
  Descriptor* self = _self;
488
389
  rb_gc_mark(self->klass);
489
390
  rb_gc_mark(self->descriptor_pool);
490
- if (self->layout && self->layout->empty_template) {
491
- layout_mark(self->layout, self->layout->empty_template);
492
- }
493
391
  }
494
392
 
495
- void Descriptor_free(void* _self) {
496
- Descriptor* self = _self;
497
- if (self->layout) {
498
- free_layout(self->layout);
499
- }
500
- xfree(self);
393
+ static const rb_data_type_t Descriptor_type = {
394
+ "Google::Protobuf::Descriptor",
395
+ {Descriptor_mark, RUBY_DEFAULT_FREE, NULL},
396
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
397
+ };
398
+
399
+ static Descriptor* ruby_to_Descriptor(VALUE val) {
400
+ Descriptor* ret;
401
+ TypedData_Get_Struct(val, Descriptor, &Descriptor_type, ret);
402
+ return ret;
501
403
  }
502
404
 
503
405
  /*
@@ -509,42 +411,24 @@ void Descriptor_free(void* _self) {
509
411
  * it is added to a pool, after which it becomes immutable (as part of a
510
412
  * finalization process).
511
413
  */
512
- VALUE Descriptor_alloc(VALUE klass) {
414
+ static VALUE Descriptor_alloc(VALUE klass) {
513
415
  Descriptor* self = ALLOC(Descriptor);
514
- VALUE ret = TypedData_Wrap_Struct(klass, &_Descriptor_type, self);
416
+ VALUE ret = TypedData_Wrap_Struct(klass, &Descriptor_type, self);
515
417
  self->msgdef = NULL;
516
418
  self->klass = Qnil;
517
419
  self->descriptor_pool = Qnil;
518
- self->layout = NULL;
519
420
  return ret;
520
421
  }
521
422
 
522
- void Descriptor_register(VALUE module) {
523
- VALUE klass = rb_define_class_under(
524
- module, "Descriptor", rb_cObject);
525
- rb_define_alloc_func(klass, Descriptor_alloc);
526
- rb_define_method(klass, "initialize", Descriptor_initialize, 3);
527
- rb_define_method(klass, "each", Descriptor_each, 0);
528
- rb_define_method(klass, "lookup", Descriptor_lookup, 1);
529
- rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
530
- rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
531
- rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
532
- rb_define_method(klass, "name", Descriptor_name, 0);
533
- rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
534
- rb_include_module(klass, rb_mEnumerable);
535
- rb_gc_register_address(&cDescriptor);
536
- cDescriptor = klass;
537
- }
538
-
539
423
  /*
540
424
  * call-seq:
541
425
  * Descriptor.new(c_only_cookie, ptr) => Descriptor
542
426
  *
543
427
  * Creates a descriptor wrapper object. May only be called from C.
544
428
  */
545
- VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
546
- VALUE descriptor_pool, VALUE ptr) {
547
- DEFINE_SELF(Descriptor, self, _self);
429
+ static VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
430
+ VALUE descriptor_pool, VALUE ptr) {
431
+ Descriptor* self = ruby_to_Descriptor(_self);
548
432
 
549
433
  if (cookie != c_only_cookie) {
550
434
  rb_raise(rb_eRuntimeError,
@@ -563,8 +447,8 @@ VALUE Descriptor_initialize(VALUE _self, VALUE cookie,
563
447
  *
564
448
  * Returns the FileDescriptor object this message belongs to.
565
449
  */
566
- VALUE Descriptor_file_descriptor(VALUE _self) {
567
- DEFINE_SELF(Descriptor, self, _self);
450
+ static VALUE Descriptor_file_descriptor(VALUE _self) {
451
+ Descriptor* self = ruby_to_Descriptor(_self);
568
452
  return get_filedef_obj(self->descriptor_pool, upb_msgdef_file(self->msgdef));
569
453
  }
570
454
 
@@ -575,8 +459,8 @@ VALUE Descriptor_file_descriptor(VALUE _self) {
575
459
  * Returns the name of this message type as a fully-qualified string (e.g.,
576
460
  * My.Package.MessageType).
577
461
  */
578
- VALUE Descriptor_name(VALUE _self) {
579
- DEFINE_SELF(Descriptor, self, _self);
462
+ static VALUE Descriptor_name(VALUE _self) {
463
+ Descriptor* self = ruby_to_Descriptor(_self);
580
464
  return rb_str_maybe_null(upb_msgdef_fullname(self->msgdef));
581
465
  }
582
466
 
@@ -586,8 +470,8 @@ VALUE Descriptor_name(VALUE _self) {
586
470
  *
587
471
  * Iterates over fields in this message type, yielding to the block on each one.
588
472
  */
589
- VALUE Descriptor_each(VALUE _self) {
590
- DEFINE_SELF(Descriptor, self, _self);
473
+ static VALUE Descriptor_each(VALUE _self) {
474
+ Descriptor* self = ruby_to_Descriptor(_self);
591
475
 
592
476
  upb_msg_field_iter it;
593
477
  for (upb_msg_field_begin(&it, self->msgdef);
@@ -607,8 +491,8 @@ VALUE Descriptor_each(VALUE _self) {
607
491
  * Returns the field descriptor for the field with the given name, if present,
608
492
  * or nil if none.
609
493
  */
610
- VALUE Descriptor_lookup(VALUE _self, VALUE name) {
611
- DEFINE_SELF(Descriptor, self, _self);
494
+ static VALUE Descriptor_lookup(VALUE _self, VALUE name) {
495
+ Descriptor* self = ruby_to_Descriptor(_self);
612
496
  const char* s = get_str(name);
613
497
  const upb_fielddef* field = upb_msgdef_ntofz(self->msgdef, s);
614
498
  if (field == NULL) {
@@ -624,8 +508,8 @@ VALUE Descriptor_lookup(VALUE _self, VALUE name) {
624
508
  * Invokes the given block for each oneof in this message type, passing the
625
509
  * corresponding OneofDescriptor.
626
510
  */
627
- VALUE Descriptor_each_oneof(VALUE _self) {
628
- DEFINE_SELF(Descriptor, self, _self);
511
+ static VALUE Descriptor_each_oneof(VALUE _self) {
512
+ Descriptor* self = ruby_to_Descriptor(_self);
629
513
 
630
514
  upb_msg_oneof_iter it;
631
515
  for (upb_msg_oneof_begin(&it, self->msgdef);
@@ -645,8 +529,8 @@ VALUE Descriptor_each_oneof(VALUE _self) {
645
529
  * Returns the oneof descriptor for the oneof with the given name, if present,
646
530
  * or nil if none.
647
531
  */
648
- VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
649
- DEFINE_SELF(Descriptor, self, _self);
532
+ static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
533
+ Descriptor* self = ruby_to_Descriptor(_self);
650
534
  const char* s = get_str(name);
651
535
  const upb_oneofdef* oneof = upb_msgdef_ntooz(self->msgdef, s);
652
536
  if (oneof == NULL) {
@@ -661,32 +545,62 @@ VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) {
661
545
  *
662
546
  * Returns the Ruby class created for this message type.
663
547
  */
664
- VALUE Descriptor_msgclass(VALUE _self) {
665
- DEFINE_SELF(Descriptor, self, _self);
548
+ static VALUE Descriptor_msgclass(VALUE _self) {
549
+ Descriptor* self = ruby_to_Descriptor(_self);
666
550
  if (self->klass == Qnil) {
667
551
  self->klass = build_class_from_descriptor(_self);
668
552
  }
669
553
  return self->klass;
670
554
  }
671
555
 
556
+ static void Descriptor_register(VALUE module) {
557
+ VALUE klass = rb_define_class_under(
558
+ module, "Descriptor", rb_cObject);
559
+ rb_define_alloc_func(klass, Descriptor_alloc);
560
+ rb_define_method(klass, "initialize", Descriptor_initialize, 3);
561
+ rb_define_method(klass, "each", Descriptor_each, 0);
562
+ rb_define_method(klass, "lookup", Descriptor_lookup, 1);
563
+ rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0);
564
+ rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1);
565
+ rb_define_method(klass, "msgclass", Descriptor_msgclass, 0);
566
+ rb_define_method(klass, "name", Descriptor_name, 0);
567
+ rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0);
568
+ rb_include_module(klass, rb_mEnumerable);
569
+ rb_gc_register_address(&cDescriptor);
570
+ cDescriptor = klass;
571
+ }
572
+
672
573
  // -----------------------------------------------------------------------------
673
574
  // FileDescriptor.
674
575
  // -----------------------------------------------------------------------------
675
576
 
676
- DEFINE_CLASS(FileDescriptor, "Google::Protobuf::FileDescriptor");
577
+ typedef struct {
578
+ const upb_filedef* filedef;
579
+ VALUE descriptor_pool; // Owns the upb_filedef.
580
+ } FileDescriptor;
677
581
 
678
- void FileDescriptor_mark(void* _self) {
582
+ static VALUE cFileDescriptor = Qnil;
583
+
584
+ static void FileDescriptor_mark(void* _self) {
679
585
  FileDescriptor* self = _self;
680
586
  rb_gc_mark(self->descriptor_pool);
681
587
  }
682
588
 
683
- void FileDescriptor_free(void* _self) {
684
- xfree(_self);
589
+ static const rb_data_type_t FileDescriptor_type = {
590
+ "Google::Protobuf::FileDescriptor",
591
+ {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
592
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
593
+ };
594
+
595
+ static FileDescriptor* ruby_to_FileDescriptor(VALUE val) {
596
+ FileDescriptor* ret;
597
+ TypedData_Get_Struct(val, FileDescriptor, &FileDescriptor_type, ret);
598
+ return ret;
685
599
  }
686
600
 
687
- VALUE FileDescriptor_alloc(VALUE klass) {
601
+ static VALUE FileDescriptor_alloc(VALUE klass) {
688
602
  FileDescriptor* self = ALLOC(FileDescriptor);
689
- VALUE ret = TypedData_Wrap_Struct(klass, &_FileDescriptor_type, self);
603
+ VALUE ret = TypedData_Wrap_Struct(klass, &FileDescriptor_type, self);
690
604
  self->descriptor_pool = Qnil;
691
605
  self->filedef = NULL;
692
606
  return ret;
@@ -699,9 +613,9 @@ VALUE FileDescriptor_alloc(VALUE klass) {
699
613
  * Returns a new file descriptor. The syntax must be set before it's passed
700
614
  * to a builder.
701
615
  */
702
- VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
616
+ static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
703
617
  VALUE descriptor_pool, VALUE ptr) {
704
- DEFINE_SELF(FileDescriptor, self, _self);
618
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
705
619
 
706
620
  if (cookie != c_only_cookie) {
707
621
  rb_raise(rb_eRuntimeError,
@@ -714,25 +628,14 @@ VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie,
714
628
  return Qnil;
715
629
  }
716
630
 
717
- void FileDescriptor_register(VALUE module) {
718
- VALUE klass = rb_define_class_under(
719
- module, "FileDescriptor", rb_cObject);
720
- rb_define_alloc_func(klass, FileDescriptor_alloc);
721
- rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
722
- rb_define_method(klass, "name", FileDescriptor_name, 0);
723
- rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
724
- rb_gc_register_address(&cFileDescriptor);
725
- cFileDescriptor = klass;
726
- }
727
-
728
631
  /*
729
632
  * call-seq:
730
633
  * FileDescriptor.name => name
731
634
  *
732
635
  * Returns the name of the file.
733
636
  */
734
- VALUE FileDescriptor_name(VALUE _self) {
735
- DEFINE_SELF(FileDescriptor, self, _self);
637
+ static VALUE FileDescriptor_name(VALUE _self) {
638
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
736
639
  const char* name = upb_filedef_name(self->filedef);
737
640
  return name == NULL ? Qnil : rb_str_new2(name);
738
641
  }
@@ -746,8 +649,8 @@ VALUE FileDescriptor_name(VALUE _self) {
746
649
  * Valid syntax versions are:
747
650
  * :proto2 or :proto3.
748
651
  */
749
- VALUE FileDescriptor_syntax(VALUE _self) {
750
- DEFINE_SELF(FileDescriptor, self, _self);
652
+ static VALUE FileDescriptor_syntax(VALUE _self) {
653
+ FileDescriptor* self = ruby_to_FileDescriptor(_self);
751
654
 
752
655
  switch (upb_filedef_syntax(self->filedef)) {
753
656
  case UPB_SYNTAX_PROTO3: return ID2SYM(rb_intern("proto3"));
@@ -756,19 +659,43 @@ VALUE FileDescriptor_syntax(VALUE _self) {
756
659
  }
757
660
  }
758
661
 
662
+ static void FileDescriptor_register(VALUE module) {
663
+ VALUE klass = rb_define_class_under(
664
+ module, "FileDescriptor", rb_cObject);
665
+ rb_define_alloc_func(klass, FileDescriptor_alloc);
666
+ rb_define_method(klass, "initialize", FileDescriptor_initialize, 3);
667
+ rb_define_method(klass, "name", FileDescriptor_name, 0);
668
+ rb_define_method(klass, "syntax", FileDescriptor_syntax, 0);
669
+ rb_gc_register_address(&cFileDescriptor);
670
+ cFileDescriptor = klass;
671
+ }
672
+
759
673
  // -----------------------------------------------------------------------------
760
674
  // FieldDescriptor.
761
675
  // -----------------------------------------------------------------------------
762
676
 
763
- DEFINE_CLASS(FieldDescriptor, "Google::Protobuf::FieldDescriptor");
677
+ typedef struct {
678
+ const upb_fielddef* fielddef;
679
+ VALUE descriptor_pool; // Owns the upb_fielddef.
680
+ } FieldDescriptor;
681
+
682
+ static VALUE cFieldDescriptor = Qnil;
764
683
 
765
- void FieldDescriptor_mark(void* _self) {
684
+ static void FieldDescriptor_mark(void* _self) {
766
685
  FieldDescriptor* self = _self;
767
686
  rb_gc_mark(self->descriptor_pool);
768
687
  }
769
688
 
770
- void FieldDescriptor_free(void* _self) {
771
- xfree(_self);
689
+ static const rb_data_type_t FieldDescriptor_type = {
690
+ "Google::Protobuf::FieldDescriptor",
691
+ {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
692
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
693
+ };
694
+
695
+ static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) {
696
+ FieldDescriptor* ret;
697
+ TypedData_Get_Struct(val, FieldDescriptor, &FieldDescriptor_type, ret);
698
+ return ret;
772
699
  }
773
700
 
774
701
  /*
@@ -778,42 +705,22 @@ void FieldDescriptor_free(void* _self) {
778
705
  * Returns a new field descriptor. Its name, type, etc. must be set before it is
779
706
  * added to a message type.
780
707
  */
781
- VALUE FieldDescriptor_alloc(VALUE klass) {
708
+ static VALUE FieldDescriptor_alloc(VALUE klass) {
782
709
  FieldDescriptor* self = ALLOC(FieldDescriptor);
783
- VALUE ret = TypedData_Wrap_Struct(klass, &_FieldDescriptor_type, self);
710
+ VALUE ret = TypedData_Wrap_Struct(klass, &FieldDescriptor_type, self);
784
711
  self->fielddef = NULL;
785
712
  return ret;
786
713
  }
787
714
 
788
- void FieldDescriptor_register(VALUE module) {
789
- VALUE klass = rb_define_class_under(
790
- module, "FieldDescriptor", rb_cObject);
791
- rb_define_alloc_func(klass, FieldDescriptor_alloc);
792
- rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
793
- rb_define_method(klass, "name", FieldDescriptor_name, 0);
794
- rb_define_method(klass, "type", FieldDescriptor_type, 0);
795
- rb_define_method(klass, "default", FieldDescriptor_default, 0);
796
- rb_define_method(klass, "label", FieldDescriptor_label, 0);
797
- rb_define_method(klass, "number", FieldDescriptor_number, 0);
798
- rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
799
- rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
800
- rb_define_method(klass, "has?", FieldDescriptor_has, 1);
801
- rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
802
- rb_define_method(klass, "get", FieldDescriptor_get, 1);
803
- rb_define_method(klass, "set", FieldDescriptor_set, 2);
804
- rb_gc_register_address(&cFieldDescriptor);
805
- cFieldDescriptor = klass;
806
- }
807
-
808
715
  /*
809
716
  * call-seq:
810
717
  * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor
811
718
  *
812
719
  * Creates a descriptor wrapper object. May only be called from C.
813
720
  */
814
- VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
815
- VALUE descriptor_pool, VALUE ptr) {
816
- DEFINE_SELF(FieldDescriptor, self, _self);
721
+ static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
722
+ VALUE descriptor_pool, VALUE ptr) {
723
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
817
724
 
818
725
  if (cookie != c_only_cookie) {
819
726
  rb_raise(rb_eRuntimeError,
@@ -832,11 +739,12 @@ VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie,
832
739
  *
833
740
  * Returns the name of this field.
834
741
  */
835
- VALUE FieldDescriptor_name(VALUE _self) {
836
- DEFINE_SELF(FieldDescriptor, self, _self);
742
+ static VALUE FieldDescriptor_name(VALUE _self) {
743
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
837
744
  return rb_str_maybe_null(upb_fielddef_name(self->fielddef));
838
745
  }
839
746
 
747
+ // Non-static, exposed to other .c files.
840
748
  upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
841
749
  if (TYPE(type) != T_SYMBOL) {
842
750
  rb_raise(rb_eArgError, "Expected symbol for field type.");
@@ -865,27 +773,7 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
865
773
  return 0;
866
774
  }
867
775
 
868
- VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
869
- switch (type) {
870
- #define CONVERT(upb, ruby) \
871
- case UPB_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
872
- CONVERT(FLOAT, float);
873
- CONVERT(DOUBLE, double);
874
- CONVERT(BOOL, bool);
875
- CONVERT(STRING, string);
876
- CONVERT(BYTES, bytes);
877
- CONVERT(MESSAGE, message);
878
- CONVERT(ENUM, enum);
879
- CONVERT(INT32, int32);
880
- CONVERT(INT64, int64);
881
- CONVERT(UINT32, uint32);
882
- CONVERT(UINT64, uint64);
883
- #undef CONVERT
884
- }
885
- return Qnil;
886
- }
887
-
888
- upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
776
+ static upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
889
777
  if (TYPE(type) != T_SYMBOL) {
890
778
  rb_raise(rb_eArgError, "Expected symbol for field type.");
891
779
  }
@@ -920,7 +808,7 @@ upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
920
808
  return 0;
921
809
  }
922
810
 
923
- VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
811
+ static VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
924
812
  switch (type) {
925
813
  #define CONVERT(upb, ruby) \
926
814
  case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
@@ -947,29 +835,6 @@ VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
947
835
  return Qnil;
948
836
  }
949
837
 
950
- VALUE ruby_to_label(VALUE label) {
951
- upb_label_t upb_label;
952
- bool converted = false;
953
-
954
- #define CONVERT(upb, ruby) \
955
- if (SYM2ID(label) == rb_intern( # ruby )) { \
956
- upb_label = UPB_LABEL_ ## upb; \
957
- converted = true; \
958
- }
959
-
960
- CONVERT(OPTIONAL, optional);
961
- CONVERT(REQUIRED, required);
962
- CONVERT(REPEATED, repeated);
963
-
964
- #undef CONVERT
965
-
966
- if (!converted) {
967
- rb_raise(rb_eArgError, "Unknown field label.");
968
- }
969
-
970
- return upb_label;
971
- }
972
-
973
838
  /*
974
839
  * call-seq:
975
840
  * FieldDescriptor.type => type
@@ -980,8 +845,8 @@ VALUE ruby_to_label(VALUE label) {
980
845
  * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
981
846
  * :bytes, :message.
982
847
  */
983
- VALUE FieldDescriptor_type(VALUE _self) {
984
- DEFINE_SELF(FieldDescriptor, self, _self);
848
+ static VALUE FieldDescriptor__type(VALUE _self) {
849
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
985
850
  return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
986
851
  }
987
852
 
@@ -991,9 +856,16 @@ VALUE FieldDescriptor_type(VALUE _self) {
991
856
  *
992
857
  * Returns this field's default, as a Ruby object, or nil if not yet set.
993
858
  */
994
- VALUE FieldDescriptor_default(VALUE _self) {
995
- DEFINE_SELF(FieldDescriptor, self, _self);
996
- return layout_get_default(self->fielddef);
859
+ static VALUE FieldDescriptor_default(VALUE _self) {
860
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
861
+ const upb_fielddef *f = self->fielddef;
862
+ upb_msgval default_val = {0};
863
+ if (upb_fielddef_issubmsg(f)) {
864
+ return Qnil;
865
+ } else if (!upb_fielddef_isseq(f)) {
866
+ default_val = upb_fielddef_default(f);
867
+ }
868
+ return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
997
869
  }
998
870
 
999
871
  /*
@@ -1005,8 +877,8 @@ VALUE FieldDescriptor_default(VALUE _self) {
1005
877
  * Valid field labels are:
1006
878
  * :optional, :repeated
1007
879
  */
1008
- VALUE FieldDescriptor_label(VALUE _self) {
1009
- DEFINE_SELF(FieldDescriptor, self, _self);
880
+ static VALUE FieldDescriptor_label(VALUE _self) {
881
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1010
882
  switch (upb_fielddef_label(self->fielddef)) {
1011
883
  #define CONVERT(upb, ruby) \
1012
884
  case UPB_LABEL_ ## upb : return ID2SYM(rb_intern( # ruby ));
@@ -1027,8 +899,8 @@ VALUE FieldDescriptor_label(VALUE _self) {
1027
899
  *
1028
900
  * Returns the tag number for this field.
1029
901
  */
1030
- VALUE FieldDescriptor_number(VALUE _self) {
1031
- DEFINE_SELF(FieldDescriptor, self, _self);
902
+ static VALUE FieldDescriptor_number(VALUE _self) {
903
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1032
904
  return INT2NUM(upb_fielddef_number(self->fielddef));
1033
905
  }
1034
906
 
@@ -1041,8 +913,8 @@ VALUE FieldDescriptor_number(VALUE _self) {
1041
913
  * name will be resolved within the context of the pool to which the containing
1042
914
  * message type is added.
1043
915
  */
1044
- VALUE FieldDescriptor_submsg_name(VALUE _self) {
1045
- DEFINE_SELF(FieldDescriptor, self, _self);
916
+ static VALUE FieldDescriptor_submsg_name(VALUE _self) {
917
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1046
918
  switch (upb_fielddef_type(self->fielddef)) {
1047
919
  case UPB_TYPE_ENUM:
1048
920
  return rb_str_new2(
@@ -1064,8 +936,8 @@ VALUE FieldDescriptor_submsg_name(VALUE _self) {
1064
936
  * called *until* the containing message type is added to a pool (and thus
1065
937
  * resolved).
1066
938
  */
1067
- VALUE FieldDescriptor_subtype(VALUE _self) {
1068
- DEFINE_SELF(FieldDescriptor, self, _self);
939
+ static VALUE FieldDescriptor_subtype(VALUE _self) {
940
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1069
941
  switch (upb_fielddef_type(self->fielddef)) {
1070
942
  case UPB_TYPE_ENUM:
1071
943
  return get_enumdef_obj(self->descriptor_pool,
@@ -1085,14 +957,17 @@ VALUE FieldDescriptor_subtype(VALUE _self) {
1085
957
  * Returns the value set for this field on the given message. Raises an
1086
958
  * exception if message is of the wrong type.
1087
959
  */
1088
- VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
1089
- DEFINE_SELF(FieldDescriptor, self, _self);
1090
- MessageHeader* msg;
1091
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1092
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
960
+ static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
961
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
962
+ const upb_msgdef *m;
963
+
964
+ Message_Get(msg_rb, &m);
965
+
966
+ if (m != upb_fielddef_containingtype(self->fielddef)) {
1093
967
  rb_raise(cTypeError, "get method called on wrong message type");
1094
968
  }
1095
- return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
969
+
970
+ return Message_getfield(msg_rb, self->fielddef);
1096
971
  }
1097
972
 
1098
973
  /*
@@ -1102,17 +977,18 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
1102
977
  * Returns whether the value is set on the given message. Raises an
1103
978
  * exception when calling for fields that do not have presence.
1104
979
  */
1105
- VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
1106
- DEFINE_SELF(FieldDescriptor, self, _self);
1107
- MessageHeader* msg;
1108
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1109
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
980
+ static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
981
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
982
+ const upb_msgdef *m;
983
+ const upb_msgdef *msg = Message_Get(msg_rb, &m);
984
+
985
+ if (m != upb_fielddef_containingtype(self->fielddef)) {
1110
986
  rb_raise(cTypeError, "has method called on wrong message type");
1111
987
  } else if (!upb_fielddef_haspresence(self->fielddef)) {
1112
988
  rb_raise(rb_eArgError, "does not track presence");
1113
989
  }
1114
990
 
1115
- return layout_has(msg->descriptor->layout, Message_data(msg), self->fielddef);
991
+ return upb_msg_has(msg, self->fielddef) ? Qtrue : Qfalse;
1116
992
  }
1117
993
 
1118
994
  /*
@@ -1121,15 +997,16 @@ VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) {
1121
997
  *
1122
998
  * Clears the field from the message if it's set.
1123
999
  */
1124
- VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
1125
- DEFINE_SELF(FieldDescriptor, self, _self);
1126
- MessageHeader* msg;
1127
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1128
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1000
+ static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
1001
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1002
+ const upb_msgdef *m;
1003
+ upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
1004
+
1005
+ if (m != upb_fielddef_containingtype(self->fielddef)) {
1129
1006
  rb_raise(cTypeError, "has method called on wrong message type");
1130
1007
  }
1131
1008
 
1132
- layout_clear(msg->descriptor->layout, Message_data(msg), self->fielddef);
1009
+ upb_msg_clearfield(msg, self->fielddef);
1133
1010
  return Qnil;
1134
1011
  }
1135
1012
 
@@ -1141,30 +1018,69 @@ VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) {
1141
1018
  * message. Raises an exception if message is of the wrong type. Performs the
1142
1019
  * ordinary type-checks for field setting.
1143
1020
  */
1144
- VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
1145
- DEFINE_SELF(FieldDescriptor, self, _self);
1146
- MessageHeader* msg;
1147
- TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1148
- if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
1021
+ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) {
1022
+ FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
1023
+ const upb_msgdef *m;
1024
+ upb_msgdef *msg = Message_GetMutable(msg_rb, &m);
1025
+ upb_arena *arena = Arena_get(Message_GetArena(msg_rb));
1026
+ upb_msgval msgval;
1027
+
1028
+ if (m != upb_fielddef_containingtype(self->fielddef)) {
1149
1029
  rb_raise(cTypeError, "set method called on wrong message type");
1150
1030
  }
1151
- layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value);
1031
+
1032
+ msgval = Convert_RubyToUpb(value, upb_fielddef_name(self->fielddef),
1033
+ TypeInfo_get(self->fielddef), arena);
1034
+ upb_msg_set(msg, self->fielddef, msgval, arena);
1152
1035
  return Qnil;
1153
1036
  }
1154
1037
 
1038
+ static void FieldDescriptor_register(VALUE module) {
1039
+ VALUE klass = rb_define_class_under(
1040
+ module, "FieldDescriptor", rb_cObject);
1041
+ rb_define_alloc_func(klass, FieldDescriptor_alloc);
1042
+ rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3);
1043
+ rb_define_method(klass, "name", FieldDescriptor_name, 0);
1044
+ rb_define_method(klass, "type", FieldDescriptor__type, 0);
1045
+ rb_define_method(klass, "default", FieldDescriptor_default, 0);
1046
+ rb_define_method(klass, "label", FieldDescriptor_label, 0);
1047
+ rb_define_method(klass, "number", FieldDescriptor_number, 0);
1048
+ rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
1049
+ rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0);
1050
+ rb_define_method(klass, "has?", FieldDescriptor_has, 1);
1051
+ rb_define_method(klass, "clear", FieldDescriptor_clear, 1);
1052
+ rb_define_method(klass, "get", FieldDescriptor_get, 1);
1053
+ rb_define_method(klass, "set", FieldDescriptor_set, 2);
1054
+ rb_gc_register_address(&cFieldDescriptor);
1055
+ cFieldDescriptor = klass;
1056
+ }
1057
+
1155
1058
  // -----------------------------------------------------------------------------
1156
1059
  // OneofDescriptor.
1157
1060
  // -----------------------------------------------------------------------------
1158
1061
 
1159
- DEFINE_CLASS(OneofDescriptor, "Google::Protobuf::OneofDescriptor");
1062
+ typedef struct {
1063
+ const upb_oneofdef* oneofdef;
1064
+ VALUE descriptor_pool; // Owns the upb_oneofdef.
1065
+ } OneofDescriptor;
1160
1066
 
1161
- void OneofDescriptor_mark(void* _self) {
1067
+ static VALUE cOneofDescriptor = Qnil;
1068
+
1069
+ static void OneofDescriptor_mark(void* _self) {
1162
1070
  OneofDescriptor* self = _self;
1163
1071
  rb_gc_mark(self->descriptor_pool);
1164
1072
  }
1165
1073
 
1166
- void OneofDescriptor_free(void* _self) {
1167
- xfree(_self);
1074
+ static const rb_data_type_t OneofDescriptor_type = {
1075
+ "Google::Protobuf::OneofDescriptor",
1076
+ {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1077
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1078
+ };
1079
+
1080
+ static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) {
1081
+ OneofDescriptor* ret;
1082
+ TypedData_Get_Struct(val, OneofDescriptor, &OneofDescriptor_type, ret);
1083
+ return ret;
1168
1084
  }
1169
1085
 
1170
1086
  /*
@@ -1174,35 +1090,23 @@ void OneofDescriptor_free(void* _self) {
1174
1090
  * Creates a new, empty, oneof descriptor. The oneof may only be modified prior
1175
1091
  * to being added to a message descriptor which is subsequently added to a pool.
1176
1092
  */
1177
- VALUE OneofDescriptor_alloc(VALUE klass) {
1093
+ static VALUE OneofDescriptor_alloc(VALUE klass) {
1178
1094
  OneofDescriptor* self = ALLOC(OneofDescriptor);
1179
- VALUE ret = TypedData_Wrap_Struct(klass, &_OneofDescriptor_type, self);
1095
+ VALUE ret = TypedData_Wrap_Struct(klass, &OneofDescriptor_type, self);
1180
1096
  self->oneofdef = NULL;
1181
1097
  self->descriptor_pool = Qnil;
1182
1098
  return ret;
1183
1099
  }
1184
1100
 
1185
- void OneofDescriptor_register(VALUE module) {
1186
- VALUE klass = rb_define_class_under(
1187
- module, "OneofDescriptor", rb_cObject);
1188
- rb_define_alloc_func(klass, OneofDescriptor_alloc);
1189
- rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
1190
- rb_define_method(klass, "name", OneofDescriptor_name, 0);
1191
- rb_define_method(klass, "each", OneofDescriptor_each, 0);
1192
- rb_include_module(klass, rb_mEnumerable);
1193
- rb_gc_register_address(&cOneofDescriptor);
1194
- cOneofDescriptor = klass;
1195
- }
1196
-
1197
1101
  /*
1198
1102
  * call-seq:
1199
1103
  * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor
1200
1104
  *
1201
1105
  * Creates a descriptor wrapper object. May only be called from C.
1202
1106
  */
1203
- VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
1107
+ static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
1204
1108
  VALUE descriptor_pool, VALUE ptr) {
1205
- DEFINE_SELF(OneofDescriptor, self, _self);
1109
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1206
1110
 
1207
1111
  if (cookie != c_only_cookie) {
1208
1112
  rb_raise(rb_eRuntimeError,
@@ -1221,8 +1125,8 @@ VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie,
1221
1125
  *
1222
1126
  * Returns the name of this oneof.
1223
1127
  */
1224
- VALUE OneofDescriptor_name(VALUE _self) {
1225
- DEFINE_SELF(OneofDescriptor, self, _self);
1128
+ static VALUE OneofDescriptor_name(VALUE _self) {
1129
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1226
1130
  return rb_str_maybe_null(upb_oneofdef_name(self->oneofdef));
1227
1131
  }
1228
1132
 
@@ -1232,8 +1136,8 @@ VALUE OneofDescriptor_name(VALUE _self) {
1232
1136
  *
1233
1137
  * Iterates through fields in this oneof, yielding to the block on each one.
1234
1138
  */
1235
- VALUE OneofDescriptor_each(VALUE _self) {
1236
- DEFINE_SELF(OneofDescriptor, self, _self);
1139
+ static VALUE OneofDescriptor_each(VALUE _self) {
1140
+ OneofDescriptor* self = ruby_to_OneofDescriptor(_self);
1237
1141
  upb_oneof_iter it;
1238
1142
  for (upb_oneof_begin(&it, self->oneofdef);
1239
1143
  !upb_oneof_done(&it);
@@ -1245,40 +1149,72 @@ VALUE OneofDescriptor_each(VALUE _self) {
1245
1149
  return Qnil;
1246
1150
  }
1247
1151
 
1152
+ static void OneofDescriptor_register(VALUE module) {
1153
+ VALUE klass = rb_define_class_under(
1154
+ module, "OneofDescriptor", rb_cObject);
1155
+ rb_define_alloc_func(klass, OneofDescriptor_alloc);
1156
+ rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3);
1157
+ rb_define_method(klass, "name", OneofDescriptor_name, 0);
1158
+ rb_define_method(klass, "each", OneofDescriptor_each, 0);
1159
+ rb_include_module(klass, rb_mEnumerable);
1160
+ rb_gc_register_address(&cOneofDescriptor);
1161
+ cOneofDescriptor = klass;
1162
+ }
1163
+
1248
1164
  // -----------------------------------------------------------------------------
1249
1165
  // EnumDescriptor.
1250
1166
  // -----------------------------------------------------------------------------
1251
1167
 
1252
- DEFINE_CLASS(EnumDescriptor, "Google::Protobuf::EnumDescriptor");
1168
+ typedef struct {
1169
+ const upb_enumdef* enumdef;
1170
+ VALUE module; // begins as nil
1171
+ VALUE descriptor_pool; // Owns the upb_enumdef.
1172
+ } EnumDescriptor;
1173
+
1174
+ static VALUE cEnumDescriptor = Qnil;
1253
1175
 
1254
- void EnumDescriptor_mark(void* _self) {
1176
+ static void EnumDescriptor_mark(void* _self) {
1255
1177
  EnumDescriptor* self = _self;
1256
1178
  rb_gc_mark(self->module);
1257
1179
  rb_gc_mark(self->descriptor_pool);
1258
1180
  }
1259
1181
 
1260
- void EnumDescriptor_free(void* _self) {
1261
- xfree(_self);
1182
+ static const rb_data_type_t EnumDescriptor_type = {
1183
+ "Google::Protobuf::EnumDescriptor",
1184
+ {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL},
1185
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1186
+ };
1187
+
1188
+ static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) {
1189
+ EnumDescriptor* ret;
1190
+ TypedData_Get_Struct(val, EnumDescriptor, &EnumDescriptor_type, ret);
1191
+ return ret;
1262
1192
  }
1263
1193
 
1264
- VALUE EnumDescriptor_alloc(VALUE klass) {
1194
+ static VALUE EnumDescriptor_alloc(VALUE klass) {
1265
1195
  EnumDescriptor* self = ALLOC(EnumDescriptor);
1266
- VALUE ret = TypedData_Wrap_Struct(klass, &_EnumDescriptor_type, self);
1196
+ VALUE ret = TypedData_Wrap_Struct(klass, &EnumDescriptor_type, self);
1267
1197
  self->enumdef = NULL;
1268
1198
  self->module = Qnil;
1269
1199
  self->descriptor_pool = Qnil;
1270
1200
  return ret;
1271
1201
  }
1272
1202
 
1203
+ // Exposed to other modules in defs.h.
1204
+ const upb_enumdef *EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) {
1205
+ EnumDescriptor *desc = ruby_to_EnumDescriptor(enum_desc_rb);
1206
+ return desc->enumdef;
1207
+ }
1208
+
1273
1209
  /*
1274
1210
  * call-seq:
1275
1211
  * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor
1276
1212
  *
1277
1213
  * Creates a descriptor wrapper object. May only be called from C.
1278
1214
  */
1279
- VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1280
- VALUE descriptor_pool, VALUE ptr) {
1281
- DEFINE_SELF(EnumDescriptor, self, _self);
1215
+ static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1216
+ VALUE descriptor_pool, VALUE ptr) {
1217
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1282
1218
 
1283
1219
  if (cookie != c_only_cookie) {
1284
1220
  rb_raise(rb_eRuntimeError,
@@ -1291,30 +1227,14 @@ VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie,
1291
1227
  return Qnil;
1292
1228
  }
1293
1229
 
1294
- void EnumDescriptor_register(VALUE module) {
1295
- VALUE klass = rb_define_class_under(
1296
- module, "EnumDescriptor", rb_cObject);
1297
- rb_define_alloc_func(klass, EnumDescriptor_alloc);
1298
- rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
1299
- rb_define_method(klass, "name", EnumDescriptor_name, 0);
1300
- rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1301
- rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1302
- rb_define_method(klass, "each", EnumDescriptor_each, 0);
1303
- rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1304
- rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1305
- rb_include_module(klass, rb_mEnumerable);
1306
- rb_gc_register_address(&cEnumDescriptor);
1307
- cEnumDescriptor = klass;
1308
- }
1309
-
1310
1230
  /*
1311
1231
  * call-seq:
1312
1232
  * EnumDescriptor.file_descriptor
1313
1233
  *
1314
1234
  * Returns the FileDescriptor object this enum belongs to.
1315
1235
  */
1316
- VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1317
- DEFINE_SELF(EnumDescriptor, self, _self);
1236
+ static VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1237
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1318
1238
  return get_filedef_obj(self->descriptor_pool,
1319
1239
  upb_enumdef_file(self->enumdef));
1320
1240
  }
@@ -1325,8 +1245,8 @@ VALUE EnumDescriptor_file_descriptor(VALUE _self) {
1325
1245
  *
1326
1246
  * Returns the name of this enum type.
1327
1247
  */
1328
- VALUE EnumDescriptor_name(VALUE _self) {
1329
- DEFINE_SELF(EnumDescriptor, self, _self);
1248
+ static VALUE EnumDescriptor_name(VALUE _self) {
1249
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1330
1250
  return rb_str_maybe_null(upb_enumdef_fullname(self->enumdef));
1331
1251
  }
1332
1252
 
@@ -1337,8 +1257,8 @@ VALUE EnumDescriptor_name(VALUE _self) {
1337
1257
  * Returns the numeric value corresponding to the given key name (as a Ruby
1338
1258
  * symbol), or nil if none.
1339
1259
  */
1340
- VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1341
- DEFINE_SELF(EnumDescriptor, self, _self);
1260
+ static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1261
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1342
1262
  const char* name_str= rb_id2name(SYM2ID(name));
1343
1263
  int32_t val = 0;
1344
1264
  if (upb_enumdef_ntoiz(self->enumdef, name_str, &val)) {
@@ -1355,8 +1275,8 @@ VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) {
1355
1275
  * Returns the key name (as a Ruby symbol) corresponding to the integer value,
1356
1276
  * or nil if none.
1357
1277
  */
1358
- VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1359
- DEFINE_SELF(EnumDescriptor, self, _self);
1278
+ static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1279
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1360
1280
  int32_t val = NUM2INT(number);
1361
1281
  const char* name = upb_enumdef_iton(self->enumdef, val);
1362
1282
  if (name != NULL) {
@@ -1373,8 +1293,8 @@ VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) {
1373
1293
  * Iterates over key => value mappings in this enum's definition, yielding to
1374
1294
  * the block with (key, value) arguments for each one.
1375
1295
  */
1376
- VALUE EnumDescriptor_each(VALUE _self) {
1377
- DEFINE_SELF(EnumDescriptor, self, _self);
1296
+ static VALUE EnumDescriptor_each(VALUE _self) {
1297
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1378
1298
 
1379
1299
  upb_enum_iter it;
1380
1300
  for (upb_enum_begin(&it, self->enumdef);
@@ -1394,53 +1314,365 @@ VALUE EnumDescriptor_each(VALUE _self) {
1394
1314
  *
1395
1315
  * Returns the Ruby module corresponding to this enum type.
1396
1316
  */
1397
- VALUE EnumDescriptor_enummodule(VALUE _self) {
1398
- DEFINE_SELF(EnumDescriptor, self, _self);
1317
+ static VALUE EnumDescriptor_enummodule(VALUE _self) {
1318
+ EnumDescriptor* self = ruby_to_EnumDescriptor(_self);
1399
1319
  if (self->module == Qnil) {
1400
1320
  self->module = build_module_from_enumdesc(_self);
1401
1321
  }
1402
1322
  return self->module;
1403
1323
  }
1404
1324
 
1325
+ static void EnumDescriptor_register(VALUE module) {
1326
+ VALUE klass = rb_define_class_under(
1327
+ module, "EnumDescriptor", rb_cObject);
1328
+ rb_define_alloc_func(klass, EnumDescriptor_alloc);
1329
+ rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3);
1330
+ rb_define_method(klass, "name", EnumDescriptor_name, 0);
1331
+ rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1);
1332
+ rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1);
1333
+ rb_define_method(klass, "each", EnumDescriptor_each, 0);
1334
+ rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0);
1335
+ rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0);
1336
+ rb_include_module(klass, rb_mEnumerable);
1337
+ rb_gc_register_address(&cEnumDescriptor);
1338
+ cEnumDescriptor = klass;
1339
+ }
1340
+
1341
+ // -----------------------------------------------------------------------------
1342
+ // FileBuilderContext.
1343
+ // -----------------------------------------------------------------------------
1344
+
1345
+ typedef struct {
1346
+ upb_arena *arena;
1347
+ google_protobuf_FileDescriptorProto* file_proto;
1348
+ VALUE descriptor_pool;
1349
+ } FileBuilderContext;
1350
+
1351
+ static VALUE cFileBuilderContext = Qnil;
1352
+
1353
+ static void FileBuilderContext_mark(void* _self) {
1354
+ FileBuilderContext* self = _self;
1355
+ rb_gc_mark(self->descriptor_pool);
1356
+ }
1357
+
1358
+ static void FileBuilderContext_free(void* _self) {
1359
+ FileBuilderContext* self = _self;
1360
+ upb_arena_free(self->arena);
1361
+ xfree(self);
1362
+ }
1363
+
1364
+ static const rb_data_type_t FileBuilderContext_type = {
1365
+ "Google::Protobuf::Internal::FileBuilderContext",
1366
+ {FileBuilderContext_mark, FileBuilderContext_free, NULL},
1367
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1368
+ };
1369
+
1370
+ static FileBuilderContext* ruby_to_FileBuilderContext(VALUE val) {
1371
+ FileBuilderContext* ret;
1372
+ TypedData_Get_Struct(val, FileBuilderContext, &FileBuilderContext_type, ret);
1373
+ return ret;
1374
+ }
1375
+
1376
+ static upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
1377
+ FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
1378
+ upb_strview ret;
1379
+ char *data;
1380
+
1381
+ ret.size = strlen(str);
1382
+ data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
1383
+ ret.data = data;
1384
+ memcpy(data, str, ret.size);
1385
+ /* Null-terminate required by rewrite_enum_defaults() above. */
1386
+ data[ret.size] = '\0';
1387
+ return ret;
1388
+ }
1389
+
1390
+ static upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
1391
+ return FileBuilderContext_strdup2(_self, get_str(rb_str));
1392
+ }
1393
+
1394
+ static upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
1395
+ Check_Type(rb_sym, T_SYMBOL);
1396
+ return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
1397
+ }
1398
+
1399
+ static VALUE FileBuilderContext_alloc(VALUE klass) {
1400
+ FileBuilderContext* self = ALLOC(FileBuilderContext);
1401
+ VALUE ret = TypedData_Wrap_Struct(klass, &FileBuilderContext_type, self);
1402
+ self->arena = upb_arena_new();
1403
+ self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
1404
+ self->descriptor_pool = Qnil;
1405
+ return ret;
1406
+ }
1407
+
1408
+ /*
1409
+ * call-seq:
1410
+ * FileBuilderContext.new(descriptor_pool) => context
1411
+ *
1412
+ * Create a new file builder context for the given file descriptor and
1413
+ * builder context. This class is intended to serve as a DSL context to be used
1414
+ * with #instance_eval.
1415
+ */
1416
+ static VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
1417
+ VALUE name, VALUE options) {
1418
+ FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
1419
+ self->descriptor_pool = descriptor_pool;
1420
+
1421
+ google_protobuf_FileDescriptorProto_set_name(
1422
+ self->file_proto, FileBuilderContext_strdup(_self, name));
1423
+
1424
+ // Default syntax for Ruby is proto3.
1425
+ google_protobuf_FileDescriptorProto_set_syntax(
1426
+ self->file_proto,
1427
+ FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
1428
+
1429
+ if (options != Qnil) {
1430
+ VALUE syntax;
1431
+
1432
+ Check_Type(options, T_HASH);
1433
+ syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
1434
+
1435
+ if (syntax != Qnil) {
1436
+ VALUE syntax_str;
1437
+
1438
+ Check_Type(syntax, T_SYMBOL);
1439
+ syntax_str = rb_id2str(SYM2ID(syntax));
1440
+ google_protobuf_FileDescriptorProto_set_syntax(
1441
+ self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
1442
+ }
1443
+ }
1444
+
1445
+ return Qnil;
1446
+ }
1447
+
1448
+ static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self);
1449
+
1450
+ /*
1451
+ * call-seq:
1452
+ * FileBuilderContext.add_message(name, &block)
1453
+ *
1454
+ * Creates a new, empty descriptor with the given name, and invokes the block in
1455
+ * the context of a MessageBuilderContext on that descriptor. The block can then
1456
+ * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
1457
+ * methods to define the message fields.
1458
+ *
1459
+ * This is the recommended, idiomatic way to build message definitions.
1460
+ */
1461
+ static VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
1462
+ VALUE args[2] = { _self, name };
1463
+ VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
1464
+ VALUE block = rb_block_proc();
1465
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1466
+ MessageBuilderContext_add_synthetic_oneofs(ctx);
1467
+ return Qnil;
1468
+ }
1469
+
1470
+ /* We have to do some relatively complicated logic here for backward
1471
+ * compatibility.
1472
+ *
1473
+ * In descriptor.proto, messages are nested inside other messages if that is
1474
+ * what the original .proto file looks like. For example, suppose we have this
1475
+ * foo.proto:
1476
+ *
1477
+ * package foo;
1478
+ * message Bar {
1479
+ * message Baz {}
1480
+ * }
1481
+ *
1482
+ * The descriptor for this must look like this:
1483
+ *
1484
+ * file {
1485
+ * name: "test.proto"
1486
+ * package: "foo"
1487
+ * message_type {
1488
+ * name: "Bar"
1489
+ * nested_type {
1490
+ * name: "Baz"
1491
+ * }
1492
+ * }
1493
+ * }
1494
+ *
1495
+ * However, the Ruby generated code has always generated messages in a flat,
1496
+ * non-nested way:
1497
+ *
1498
+ * Google::Protobuf::DescriptorPool.generated_pool.build do
1499
+ * add_message "foo.Bar" do
1500
+ * end
1501
+ * add_message "foo.Bar.Baz" do
1502
+ * end
1503
+ * end
1504
+ *
1505
+ * Here we need to do a translation where we turn this generated code into the
1506
+ * above descriptor. We need to infer that "foo" is the package name, and not
1507
+ * a message itself.
1508
+ *
1509
+ * We delegate to Ruby to compute the transformation, for more concice and
1510
+ * readable code than we can do in C */
1511
+ static void rewrite_names(VALUE _file_builder,
1512
+ google_protobuf_FileDescriptorProto* file_proto) {
1513
+ FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
1514
+ upb_arena *arena = file_builder->arena;
1515
+ // Build params (package, msg_names, enum_names).
1516
+ VALUE package = Qnil;
1517
+ VALUE msg_names = rb_ary_new();
1518
+ VALUE enum_names = rb_ary_new();
1519
+ size_t msg_count, enum_count, i;
1520
+ VALUE new_package, nesting, msg_ents, enum_ents;
1521
+ google_protobuf_DescriptorProto** msgs;
1522
+ google_protobuf_EnumDescriptorProto** enums;
1523
+
1524
+ if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
1525
+ upb_strview package_str =
1526
+ google_protobuf_FileDescriptorProto_package(file_proto);
1527
+ package = rb_str_new(package_str.data, package_str.size);
1528
+ }
1529
+
1530
+ msgs = google_protobuf_FileDescriptorProto_mutable_message_type(file_proto,
1531
+ &msg_count);
1532
+ for (i = 0; i < msg_count; i++) {
1533
+ upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
1534
+ rb_ary_push(msg_names, rb_str_new(name.data, name.size));
1535
+ }
1536
+
1537
+ enums = google_protobuf_FileDescriptorProto_mutable_enum_type(file_proto,
1538
+ &enum_count);
1539
+ for (i = 0; i < enum_count; i++) {
1540
+ upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
1541
+ rb_ary_push(enum_names, rb_str_new(name.data, name.size));
1542
+ }
1543
+
1544
+ {
1545
+ // Call Ruby code to calculate package name and nesting.
1546
+ VALUE args[3] = { package, msg_names, enum_names };
1547
+ VALUE internal = rb_eval_string("Google::Protobuf::Internal");
1548
+ VALUE ret = rb_funcallv(internal, rb_intern("fixup_descriptor"), 3, args);
1549
+
1550
+ new_package = rb_ary_entry(ret, 0);
1551
+ nesting = rb_ary_entry(ret, 1);
1552
+ }
1553
+
1554
+ // Rewrite package and names.
1555
+ if (new_package != Qnil) {
1556
+ upb_strview new_package_str =
1557
+ FileBuilderContext_strdup(_file_builder, new_package);
1558
+ google_protobuf_FileDescriptorProto_set_package(file_proto,
1559
+ new_package_str);
1560
+ }
1561
+
1562
+ for (i = 0; i < msg_count; i++) {
1563
+ upb_strview name = google_protobuf_DescriptorProto_name(msgs[i]);
1564
+ remove_path(&name);
1565
+ google_protobuf_DescriptorProto_set_name(msgs[i], name);
1566
+ }
1567
+
1568
+ for (i = 0; i < enum_count; i++) {
1569
+ upb_strview name = google_protobuf_EnumDescriptorProto_name(enums[i]);
1570
+ remove_path(&name);
1571
+ google_protobuf_EnumDescriptorProto_set_name(enums[i], name);
1572
+ }
1573
+
1574
+ // Rewrite nesting.
1575
+ msg_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("msgs")));
1576
+ enum_ents = rb_hash_aref(nesting, ID2SYM(rb_intern("enums")));
1577
+
1578
+ Check_Type(msg_ents, T_ARRAY);
1579
+ Check_Type(enum_ents, T_ARRAY);
1580
+
1581
+ for (i = 0; i < (size_t)RARRAY_LEN(msg_ents); i++) {
1582
+ VALUE msg_ent = rb_ary_entry(msg_ents, i);
1583
+ VALUE pos = rb_hash_aref(msg_ent, ID2SYM(rb_intern("pos")));
1584
+ msgs[i] = msgs[NUM2INT(pos)];
1585
+ rewrite_nesting(msg_ent, msgs[i], msgs, enums, arena);
1586
+ }
1587
+
1588
+ for (i = 0; i < (size_t)RARRAY_LEN(enum_ents); i++) {
1589
+ VALUE enum_pos = rb_ary_entry(enum_ents, i);
1590
+ enums[i] = enums[NUM2INT(enum_pos)];
1591
+ }
1592
+
1593
+ google_protobuf_FileDescriptorProto_resize_message_type(
1594
+ file_proto, RARRAY_LEN(msg_ents), arena);
1595
+ google_protobuf_FileDescriptorProto_resize_enum_type(
1596
+ file_proto, RARRAY_LEN(enum_ents), arena);
1597
+ }
1598
+
1599
+ /*
1600
+ * call-seq:
1601
+ * FileBuilderContext.add_enum(name, &block)
1602
+ *
1603
+ * Creates a new, empty enum descriptor with the given name, and invokes the
1604
+ * block in the context of an EnumBuilderContext on that descriptor. The block
1605
+ * can then call EnumBuilderContext#add_value to define the enum values.
1606
+ *
1607
+ * This is the recommended, idiomatic way to build enum definitions.
1608
+ */
1609
+ static VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
1610
+ VALUE args[2] = { _self, name };
1611
+ VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
1612
+ VALUE block = rb_block_proc();
1613
+ rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
1614
+ return Qnil;
1615
+ }
1616
+
1617
+ static void FileBuilderContext_build(VALUE _self) {
1618
+ FileBuilderContext* self = ruby_to_FileBuilderContext(_self);
1619
+ DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
1620
+ upb_status status;
1621
+
1622
+ rewrite_enum_defaults(pool->symtab, self->file_proto);
1623
+ rewrite_names(_self, self->file_proto);
1624
+
1625
+ upb_status_clear(&status);
1626
+ if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
1627
+ rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
1628
+ upb_status_errmsg(&status));
1629
+ }
1630
+ }
1631
+
1632
+ static void FileBuilderContext_register(VALUE module) {
1633
+ VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
1634
+ rb_define_alloc_func(klass, FileBuilderContext_alloc);
1635
+ rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
1636
+ rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
1637
+ rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
1638
+ rb_gc_register_address(&cFileBuilderContext);
1639
+ cFileBuilderContext = klass;
1640
+ }
1641
+
1405
1642
  // -----------------------------------------------------------------------------
1406
1643
  // MessageBuilderContext.
1407
1644
  // -----------------------------------------------------------------------------
1408
1645
 
1409
- DEFINE_CLASS(MessageBuilderContext,
1410
- "Google::Protobuf::Internal::MessageBuilderContext");
1646
+ typedef struct {
1647
+ google_protobuf_DescriptorProto* msg_proto;
1648
+ VALUE file_builder;
1649
+ } MessageBuilderContext;
1650
+
1651
+ static VALUE cMessageBuilderContext = Qnil;
1411
1652
 
1412
- void MessageBuilderContext_mark(void* _self) {
1653
+ static void MessageBuilderContext_mark(void* _self) {
1413
1654
  MessageBuilderContext* self = _self;
1414
1655
  rb_gc_mark(self->file_builder);
1415
1656
  }
1416
1657
 
1417
- void MessageBuilderContext_free(void* _self) {
1418
- MessageBuilderContext* self = _self;
1419
- xfree(self);
1420
- }
1658
+ static const rb_data_type_t MessageBuilderContext_type = {
1659
+ "Google::Protobuf::Internal::MessageBuilderContext",
1660
+ {MessageBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
1661
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
1662
+ };
1421
1663
 
1422
- VALUE MessageBuilderContext_alloc(VALUE klass) {
1423
- MessageBuilderContext* self = ALLOC(MessageBuilderContext);
1424
- VALUE ret = TypedData_Wrap_Struct(
1425
- klass, &_MessageBuilderContext_type, self);
1426
- self->file_builder = Qnil;
1664
+ static MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE val) {
1665
+ MessageBuilderContext* ret;
1666
+ TypedData_Get_Struct(val, MessageBuilderContext, &MessageBuilderContext_type,
1667
+ ret);
1427
1668
  return ret;
1428
1669
  }
1429
1670
 
1430
- void MessageBuilderContext_register(VALUE module) {
1431
- VALUE klass = rb_define_class_under(
1432
- module, "MessageBuilderContext", rb_cObject);
1433
- rb_define_alloc_func(klass, MessageBuilderContext_alloc);
1434
- rb_define_method(klass, "initialize",
1435
- MessageBuilderContext_initialize, 2);
1436
- rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
1437
- rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
1438
- rb_define_method(klass, "required", MessageBuilderContext_required, -1);
1439
- rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
1440
- rb_define_method(klass, "map", MessageBuilderContext_map, -1);
1441
- rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
1442
- rb_gc_register_address(&cMessageBuilderContext);
1443
- cMessageBuilderContext = klass;
1671
+ static VALUE MessageBuilderContext_alloc(VALUE klass) {
1672
+ MessageBuilderContext* self = ALLOC(MessageBuilderContext);
1673
+ VALUE ret = TypedData_Wrap_Struct(klass, &MessageBuilderContext_type, self);
1674
+ self->file_builder = Qnil;
1675
+ return ret;
1444
1676
  }
1445
1677
 
1446
1678
  /*
@@ -1451,10 +1683,9 @@ void MessageBuilderContext_register(VALUE module) {
1451
1683
  * builder context. This class is intended to serve as a DSL context to be used
1452
1684
  * with #instance_eval.
1453
1685
  */
1454
- VALUE MessageBuilderContext_initialize(VALUE _self,
1455
- VALUE _file_builder,
1456
- VALUE name) {
1457
- DEFINE_SELF(MessageBuilderContext, self, _self);
1686
+ static VALUE MessageBuilderContext_initialize(VALUE _self, VALUE _file_builder,
1687
+ VALUE name) {
1688
+ MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
1458
1689
  FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
1459
1690
  google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
1460
1691
 
@@ -1472,7 +1703,7 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
1472
1703
  VALUE type, VALUE number, VALUE type_class,
1473
1704
  VALUE options, int oneof_index,
1474
1705
  bool proto3_optional) {
1475
- DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb);
1706
+ MessageBuilderContext* self = ruby_to_MessageBuilderContext(msgbuilder_rb);
1476
1707
  FileBuilderContext* file_context =
1477
1708
  ruby_to_FileBuilderContext(self->file_builder);
1478
1709
  google_protobuf_FieldDescriptorProto* field_proto;
@@ -1527,9 +1758,16 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
1527
1758
  }
1528
1759
  }
1529
1760
 
1761
+ #if RUBY_API_VERSION_CODE >= 20700
1762
+ static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
1763
+ const VALUE* argv, VALUE blockarg) {
1764
+ (void)blockarg;
1765
+ #else
1530
1766
  static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
1531
1767
  VALUE* argv) {
1532
- DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
1768
+ #endif
1769
+ MessageBuilderContext* message_builder =
1770
+ ruby_to_MessageBuilderContext(_message_builder);
1533
1771
  VALUE type_class = rb_ary_entry(types, 2);
1534
1772
  FileBuilderContext* file_context =
1535
1773
  ruby_to_FileBuilderContext(message_builder->file_builder);
@@ -1596,8 +1834,8 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1596
1834
  * FieldDescriptor#type=) and the type_class must be a string, if present (as
1597
1835
  * accepted by FieldDescriptor#submsg_name=).
1598
1836
  */
1599
- VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
1600
- VALUE _self) {
1837
+ static VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
1838
+ VALUE _self) {
1601
1839
  VALUE name, type, number;
1602
1840
  VALUE type_class, options = Qnil;
1603
1841
 
@@ -1630,7 +1868,8 @@ VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv,
1630
1868
  * completeness. Any attempt to add a message type with required fields to a
1631
1869
  * pool will currently result in an error.
1632
1870
  */
1633
- VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1871
+ static VALUE MessageBuilderContext_required(int argc, VALUE* argv,
1872
+ VALUE _self) {
1634
1873
  VALUE name, type, number;
1635
1874
  VALUE type_class, options = Qnil;
1636
1875
 
@@ -1658,7 +1897,8 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
1658
1897
  * symbol (as accepted by FieldDescriptor#type=) and the type_class must be a
1659
1898
  * string, if present (as accepted by FieldDescriptor#submsg_name=).
1660
1899
  */
1661
- VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1900
+ static VALUE MessageBuilderContext_repeated(int argc, VALUE* argv,
1901
+ VALUE _self) {
1662
1902
  VALUE name, type, number, type_class;
1663
1903
 
1664
1904
  if (argc < 3) {
@@ -1687,8 +1927,8 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
1687
1927
  * type_class must be a string, if present (as accepted by
1688
1928
  * FieldDescriptor#submsg_name=).
1689
1929
  */
1690
- VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1691
- DEFINE_SELF(MessageBuilderContext, self, _self);
1930
+ static VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1931
+ MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
1692
1932
  VALUE name, key_type, value_type, number, type_class;
1693
1933
  VALUE mapentry_desc_name;
1694
1934
  FileBuilderContext* file_builder;
@@ -1717,14 +1957,6 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1717
1957
 
1718
1958
  file_builder = ruby_to_FileBuilderContext(self->file_builder);
1719
1959
 
1720
- // TODO(haberman): remove this restriction, maps are supported in proto2.
1721
- if (upb_strview_eql(
1722
- google_protobuf_FileDescriptorProto_syntax(file_builder->file_proto),
1723
- upb_strview_makez("proto2"))) {
1724
- rb_raise(rb_eArgError,
1725
- "Cannot add a native map field using proto2 syntax.");
1726
- }
1727
-
1728
1960
  // Create a new message descriptor for the map entry message, and create a
1729
1961
  // repeated submessage field here with that type.
1730
1962
  msg_name = google_protobuf_DescriptorProto_name(self->msg_proto);
@@ -1768,8 +2000,8 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
1768
2000
  *
1769
2001
  * This is the recommended, idiomatic way to build oneof definitions.
1770
2002
  */
1771
- VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1772
- DEFINE_SELF(MessageBuilderContext, self, _self);
2003
+ static VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
2004
+ MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
1773
2005
  size_t oneof_count;
1774
2006
  FileBuilderContext* file_context =
1775
2007
  ruby_to_FileBuilderContext(self->file_builder);
@@ -1795,8 +2027,8 @@ VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) {
1795
2027
  return Qnil;
1796
2028
  }
1797
2029
 
1798
- void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
1799
- DEFINE_SELF(MessageBuilderContext, self, _self);
2030
+ static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
2031
+ MessageBuilderContext* self = ruby_to_MessageBuilderContext(_self);
1800
2032
  FileBuilderContext* file_context =
1801
2033
  ruby_to_FileBuilderContext(self->file_builder);
1802
2034
  size_t field_count, oneof_count;
@@ -1845,42 +2077,59 @@ void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) {
1845
2077
  }
1846
2078
  }
1847
2079
 
2080
+ static void MessageBuilderContext_register(VALUE module) {
2081
+ VALUE klass = rb_define_class_under(
2082
+ module, "MessageBuilderContext", rb_cObject);
2083
+ rb_define_alloc_func(klass, MessageBuilderContext_alloc);
2084
+ rb_define_method(klass, "initialize",
2085
+ MessageBuilderContext_initialize, 2);
2086
+ rb_define_method(klass, "optional", MessageBuilderContext_optional, -1);
2087
+ rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1);
2088
+ rb_define_method(klass, "required", MessageBuilderContext_required, -1);
2089
+ rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1);
2090
+ rb_define_method(klass, "map", MessageBuilderContext_map, -1);
2091
+ rb_define_method(klass, "oneof", MessageBuilderContext_oneof, 1);
2092
+ rb_gc_register_address(&cMessageBuilderContext);
2093
+ cMessageBuilderContext = klass;
2094
+ }
2095
+
1848
2096
  // -----------------------------------------------------------------------------
1849
2097
  // OneofBuilderContext.
1850
2098
  // -----------------------------------------------------------------------------
1851
2099
 
1852
- DEFINE_CLASS(OneofBuilderContext,
1853
- "Google::Protobuf::Internal::OneofBuilderContext");
2100
+ typedef struct {
2101
+ int oneof_index;
2102
+ VALUE message_builder;
2103
+ } OneofBuilderContext;
2104
+
2105
+ static VALUE cOneofBuilderContext = Qnil;
1854
2106
 
1855
2107
  void OneofBuilderContext_mark(void* _self) {
1856
2108
  OneofBuilderContext* self = _self;
1857
2109
  rb_gc_mark(self->message_builder);
1858
2110
  }
1859
2111
 
1860
- void OneofBuilderContext_free(void* _self) {
1861
- xfree(_self);
2112
+ static const rb_data_type_t OneofBuilderContext_type = {
2113
+ "Google::Protobuf::Internal::OneofBuilderContext",
2114
+ {OneofBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
2115
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
2116
+ };
2117
+
2118
+ static OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE val) {
2119
+ OneofBuilderContext* ret;
2120
+ TypedData_Get_Struct(val, OneofBuilderContext, &OneofBuilderContext_type,
2121
+ ret);
2122
+ return ret;
1862
2123
  }
1863
2124
 
1864
- VALUE OneofBuilderContext_alloc(VALUE klass) {
2125
+ static VALUE OneofBuilderContext_alloc(VALUE klass) {
1865
2126
  OneofBuilderContext* self = ALLOC(OneofBuilderContext);
1866
- VALUE ret = TypedData_Wrap_Struct(
1867
- klass, &_OneofBuilderContext_type, self);
2127
+ VALUE ret = TypedData_Wrap_Struct(klass, &OneofBuilderContext_type, self);
1868
2128
  self->oneof_index = 0;
1869
2129
  self->message_builder = Qnil;
1870
2130
  return ret;
1871
2131
  }
1872
2132
 
1873
- void OneofBuilderContext_register(VALUE module) {
1874
- VALUE klass = rb_define_class_under(
1875
- module, "OneofBuilderContext", rb_cObject);
1876
- rb_define_alloc_func(klass, OneofBuilderContext_alloc);
1877
- rb_define_method(klass, "initialize",
1878
- OneofBuilderContext_initialize, 2);
1879
- rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
1880
- rb_gc_register_address(&cOneofBuilderContext);
1881
- cOneofBuilderContext = klass;
1882
- }
1883
-
1884
2133
  /*
1885
2134
  * call-seq:
1886
2135
  * OneofBuilderContext.new(oneof_index, message_builder) => context
@@ -1889,10 +2138,9 @@ void OneofBuilderContext_register(VALUE module) {
1889
2138
  * builder context. This class is intended to serve as a DSL context to be used
1890
2139
  * with #instance_eval.
1891
2140
  */
1892
- VALUE OneofBuilderContext_initialize(VALUE _self,
1893
- VALUE oneof_index,
1894
- VALUE message_builder) {
1895
- DEFINE_SELF(OneofBuilderContext, self, _self);
2141
+ static VALUE OneofBuilderContext_initialize(VALUE _self, VALUE oneof_index,
2142
+ VALUE message_builder) {
2143
+ OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
1896
2144
  self->oneof_index = NUM2INT(oneof_index);
1897
2145
  self->message_builder = message_builder;
1898
2146
  return Qnil;
@@ -1908,8 +2156,8 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
1908
2156
  * (as accepted by FieldDescriptor#type=) and the type_class must be a string,
1909
2157
  * if present (as accepted by FieldDescriptor#submsg_name=).
1910
2158
  */
1911
- VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1912
- DEFINE_SELF(OneofBuilderContext, self, _self);
2159
+ static VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
2160
+ OneofBuilderContext* self = ruby_to_OneofBuilderContext(_self);
1913
2161
  VALUE name, type, number;
1914
2162
  VALUE type_class, options = Qnil;
1915
2163
 
@@ -1921,41 +2169,53 @@ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
1921
2169
  return Qnil;
1922
2170
  }
1923
2171
 
2172
+ static void OneofBuilderContext_register(VALUE module) {
2173
+ VALUE klass = rb_define_class_under(
2174
+ module, "OneofBuilderContext", rb_cObject);
2175
+ rb_define_alloc_func(klass, OneofBuilderContext_alloc);
2176
+ rb_define_method(klass, "initialize",
2177
+ OneofBuilderContext_initialize, 2);
2178
+ rb_define_method(klass, "optional", OneofBuilderContext_optional, -1);
2179
+ rb_gc_register_address(&cOneofBuilderContext);
2180
+ cOneofBuilderContext = klass;
2181
+ }
2182
+
1924
2183
  // -----------------------------------------------------------------------------
1925
2184
  // EnumBuilderContext.
1926
2185
  // -----------------------------------------------------------------------------
1927
2186
 
1928
- DEFINE_CLASS(EnumBuilderContext,
1929
- "Google::Protobuf::Internal::EnumBuilderContext");
2187
+ typedef struct {
2188
+ google_protobuf_EnumDescriptorProto* enum_proto;
2189
+ VALUE file_builder;
2190
+ } EnumBuilderContext;
2191
+
2192
+ static VALUE cEnumBuilderContext = Qnil;
1930
2193
 
1931
2194
  void EnumBuilderContext_mark(void* _self) {
1932
2195
  EnumBuilderContext* self = _self;
1933
2196
  rb_gc_mark(self->file_builder);
1934
2197
  }
1935
2198
 
1936
- void EnumBuilderContext_free(void* _self) {
1937
- xfree(_self);
2199
+ static const rb_data_type_t EnumBuilderContext_type = {
2200
+ "Google::Protobuf::Internal::EnumBuilderContext",
2201
+ {EnumBuilderContext_mark, RUBY_DEFAULT_FREE, NULL},
2202
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
2203
+ };
2204
+
2205
+ static EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE val) {
2206
+ EnumBuilderContext* ret;
2207
+ TypedData_Get_Struct(val, EnumBuilderContext, &EnumBuilderContext_type, ret);
2208
+ return ret;
1938
2209
  }
1939
2210
 
1940
- VALUE EnumBuilderContext_alloc(VALUE klass) {
2211
+ static VALUE EnumBuilderContext_alloc(VALUE klass) {
1941
2212
  EnumBuilderContext* self = ALLOC(EnumBuilderContext);
1942
- VALUE ret = TypedData_Wrap_Struct(
1943
- klass, &_EnumBuilderContext_type, self);
2213
+ VALUE ret = TypedData_Wrap_Struct(klass, &EnumBuilderContext_type, self);
1944
2214
  self->enum_proto = NULL;
1945
2215
  self->file_builder = Qnil;
1946
2216
  return ret;
1947
2217
  }
1948
2218
 
1949
- void EnumBuilderContext_register(VALUE module) {
1950
- VALUE klass = rb_define_class_under(
1951
- module, "EnumBuilderContext", rb_cObject);
1952
- rb_define_alloc_func(klass, EnumBuilderContext_alloc);
1953
- rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
1954
- rb_define_method(klass, "value", EnumBuilderContext_value, 2);
1955
- rb_gc_register_address(&cEnumBuilderContext);
1956
- cEnumBuilderContext = klass;
1957
- }
1958
-
1959
2219
  /*
1960
2220
  * call-seq:
1961
2221
  * EnumBuilderContext.new(file_builder) => context
@@ -1963,9 +2223,9 @@ void EnumBuilderContext_register(VALUE module) {
1963
2223
  * Create a new builder context around the given enum descriptor. This class is
1964
2224
  * intended to serve as a DSL context to be used with #instance_eval.
1965
2225
  */
1966
- VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
1967
- VALUE name) {
1968
- DEFINE_SELF(EnumBuilderContext, self, _self);
2226
+ static VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
2227
+ VALUE name) {
2228
+ EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
1969
2229
  FileBuilderContext* file_builder = ruby_to_FileBuilderContext(_file_builder);
1970
2230
  google_protobuf_FileDescriptorProto* file_proto = file_builder->file_proto;
1971
2231
 
@@ -1986,8 +2246,8 @@ VALUE EnumBuilderContext_initialize(VALUE _self, VALUE _file_builder,
1986
2246
  * Adds the given name => number mapping to the enum type. Name must be a Ruby
1987
2247
  * symbol.
1988
2248
  */
1989
- VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
1990
- DEFINE_SELF(EnumBuilderContext, self, _self);
2249
+ static VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
2250
+ EnumBuilderContext* self = ruby_to_EnumBuilderContext(_self);
1991
2251
  FileBuilderContext* file_builder =
1992
2252
  ruby_to_FileBuilderContext(self->file_builder);
1993
2253
  google_protobuf_EnumValueDescriptorProto* enum_value;
@@ -2003,196 +2263,53 @@ VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number) {
2003
2263
  return Qnil;
2004
2264
  }
2005
2265
 
2006
-
2007
- // -----------------------------------------------------------------------------
2008
- // FileBuilderContext.
2009
- // -----------------------------------------------------------------------------
2010
-
2011
- DEFINE_CLASS(FileBuilderContext,
2012
- "Google::Protobuf::Internal::FileBuilderContext");
2013
-
2014
- void FileBuilderContext_mark(void* _self) {
2015
- FileBuilderContext* self = _self;
2016
- rb_gc_mark(self->descriptor_pool);
2017
- }
2018
-
2019
- void FileBuilderContext_free(void* _self) {
2020
- FileBuilderContext* self = _self;
2021
- upb_arena_free(self->arena);
2022
- xfree(self);
2023
- }
2024
-
2025
- upb_strview FileBuilderContext_strdup2(VALUE _self, const char *str) {
2026
- DEFINE_SELF(FileBuilderContext, self, _self);
2027
- upb_strview ret;
2028
- char *data;
2029
-
2030
- ret.size = strlen(str);
2031
- data = upb_malloc(upb_arena_alloc(self->arena), ret.size + 1);
2032
- ret.data = data;
2033
- memcpy(data, str, ret.size);
2034
- /* Null-terminate required by rewrite_enum_defaults() above. */
2035
- data[ret.size] = '\0';
2036
- return ret;
2037
- }
2038
-
2039
- upb_strview FileBuilderContext_strdup(VALUE _self, VALUE rb_str) {
2040
- return FileBuilderContext_strdup2(_self, get_str(rb_str));
2041
- }
2042
-
2043
- upb_strview FileBuilderContext_strdup_sym(VALUE _self, VALUE rb_sym) {
2044
- Check_Type(rb_sym, T_SYMBOL);
2045
- return FileBuilderContext_strdup(_self, rb_id2str(SYM2ID(rb_sym)));
2046
- }
2047
-
2048
- VALUE FileBuilderContext_alloc(VALUE klass) {
2049
- FileBuilderContext* self = ALLOC(FileBuilderContext);
2050
- VALUE ret = TypedData_Wrap_Struct(klass, &_FileBuilderContext_type, self);
2051
- self->arena = upb_arena_new();
2052
- self->file_proto = google_protobuf_FileDescriptorProto_new(self->arena);
2053
- self->descriptor_pool = Qnil;
2054
- return ret;
2055
- }
2056
-
2057
- void FileBuilderContext_register(VALUE module) {
2058
- VALUE klass = rb_define_class_under(module, "FileBuilderContext", rb_cObject);
2059
- rb_define_alloc_func(klass, FileBuilderContext_alloc);
2060
- rb_define_method(klass, "initialize", FileBuilderContext_initialize, 3);
2061
- rb_define_method(klass, "add_message", FileBuilderContext_add_message, 1);
2062
- rb_define_method(klass, "add_enum", FileBuilderContext_add_enum, 1);
2063
- rb_gc_register_address(&cFileBuilderContext);
2064
- cFileBuilderContext = klass;
2065
- }
2066
-
2067
- /*
2068
- * call-seq:
2069
- * FileBuilderContext.new(descriptor_pool) => context
2070
- *
2071
- * Create a new file builder context for the given file descriptor and
2072
- * builder context. This class is intended to serve as a DSL context to be used
2073
- * with #instance_eval.
2074
- */
2075
- VALUE FileBuilderContext_initialize(VALUE _self, VALUE descriptor_pool,
2076
- VALUE name, VALUE options) {
2077
- DEFINE_SELF(FileBuilderContext, self, _self);
2078
- self->descriptor_pool = descriptor_pool;
2079
-
2080
- google_protobuf_FileDescriptorProto_set_name(
2081
- self->file_proto, FileBuilderContext_strdup(_self, name));
2082
-
2083
- // Default syntax for Ruby is proto3.
2084
- google_protobuf_FileDescriptorProto_set_syntax(
2085
- self->file_proto,
2086
- FileBuilderContext_strdup(_self, rb_str_new2("proto3")));
2087
-
2088
- if (options != Qnil) {
2089
- VALUE syntax;
2090
-
2091
- Check_Type(options, T_HASH);
2092
- syntax = rb_hash_lookup2(options, ID2SYM(rb_intern("syntax")), Qnil);
2093
-
2094
- if (syntax != Qnil) {
2095
- VALUE syntax_str;
2096
-
2097
- Check_Type(syntax, T_SYMBOL);
2098
- syntax_str = rb_id2str(SYM2ID(syntax));
2099
- google_protobuf_FileDescriptorProto_set_syntax(
2100
- self->file_proto, FileBuilderContext_strdup(_self, syntax_str));
2101
- }
2102
- }
2103
-
2104
- return Qnil;
2105
- }
2106
-
2107
- /*
2108
- * call-seq:
2109
- * FileBuilderContext.add_message(name, &block)
2110
- *
2111
- * Creates a new, empty descriptor with the given name, and invokes the block in
2112
- * the context of a MessageBuilderContext on that descriptor. The block can then
2113
- * call, e.g., MessageBuilderContext#optional and MessageBuilderContext#repeated
2114
- * methods to define the message fields.
2115
- *
2116
- * This is the recommended, idiomatic way to build message definitions.
2117
- */
2118
- VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) {
2119
- VALUE args[2] = { _self, name };
2120
- VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext);
2121
- VALUE block = rb_block_proc();
2122
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2123
- MessageBuilderContext_add_synthetic_oneofs(ctx);
2124
- return Qnil;
2125
- }
2126
-
2127
- /*
2128
- * call-seq:
2129
- * FileBuilderContext.add_enum(name, &block)
2130
- *
2131
- * Creates a new, empty enum descriptor with the given name, and invokes the
2132
- * block in the context of an EnumBuilderContext on that descriptor. The block
2133
- * can then call EnumBuilderContext#add_value to define the enum values.
2134
- *
2135
- * This is the recommended, idiomatic way to build enum definitions.
2136
- */
2137
- VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name) {
2138
- VALUE args[2] = { _self, name };
2139
- VALUE ctx = rb_class_new_instance(2, args, cEnumBuilderContext);
2140
- VALUE block = rb_block_proc();
2141
- rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block);
2142
- return Qnil;
2143
- }
2144
-
2145
- void FileBuilderContext_build(VALUE _self) {
2146
- DEFINE_SELF(FileBuilderContext, self, _self);
2147
- DescriptorPool* pool = ruby_to_DescriptorPool(self->descriptor_pool);
2148
- upb_status status;
2149
-
2150
- rewrite_enum_defaults(pool->symtab, self->file_proto);
2151
- rewrite_names(_self, self->file_proto);
2152
-
2153
- upb_status_clear(&status);
2154
- if (!upb_symtab_addfile(pool->symtab, self->file_proto, &status)) {
2155
- rb_raise(cTypeError, "Unable to add defs to DescriptorPool: %s",
2156
- upb_status_errmsg(&status));
2157
- }
2266
+ static void EnumBuilderContext_register(VALUE module) {
2267
+ VALUE klass = rb_define_class_under(
2268
+ module, "EnumBuilderContext", rb_cObject);
2269
+ rb_define_alloc_func(klass, EnumBuilderContext_alloc);
2270
+ rb_define_method(klass, "initialize", EnumBuilderContext_initialize, 2);
2271
+ rb_define_method(klass, "value", EnumBuilderContext_value, 2);
2272
+ rb_gc_register_address(&cEnumBuilderContext);
2273
+ cEnumBuilderContext = klass;
2158
2274
  }
2159
2275
 
2160
2276
  // -----------------------------------------------------------------------------
2161
2277
  // Builder.
2162
2278
  // -----------------------------------------------------------------------------
2163
2279
 
2164
- DEFINE_CLASS(Builder, "Google::Protobuf::Internal::Builder");
2280
+ typedef struct {
2281
+ VALUE descriptor_pool;
2282
+ VALUE default_file_builder;
2283
+ } Builder;
2165
2284
 
2166
- void Builder_mark(void* _self) {
2285
+ static VALUE cBuilder = Qnil;
2286
+
2287
+ static void Builder_mark(void* _self) {
2167
2288
  Builder* self = _self;
2168
2289
  rb_gc_mark(self->descriptor_pool);
2169
2290
  rb_gc_mark(self->default_file_builder);
2170
2291
  }
2171
2292
 
2172
- void Builder_free(void* _self) {
2173
- xfree(_self);
2293
+ static const rb_data_type_t Builder_type = {
2294
+ "Google::Protobuf::Internal::Builder",
2295
+ {Builder_mark, RUBY_DEFAULT_FREE, NULL},
2296
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
2297
+ };
2298
+
2299
+ static Builder* ruby_to_Builder(VALUE val) {
2300
+ Builder* ret;
2301
+ TypedData_Get_Struct(val, Builder, &Builder_type, ret);
2302
+ return ret;
2174
2303
  }
2175
2304
 
2176
- VALUE Builder_alloc(VALUE klass) {
2305
+ static VALUE Builder_alloc(VALUE klass) {
2177
2306
  Builder* self = ALLOC(Builder);
2178
- VALUE ret = TypedData_Wrap_Struct(
2179
- klass, &_Builder_type, self);
2307
+ VALUE ret = TypedData_Wrap_Struct(klass, &Builder_type, self);
2180
2308
  self->descriptor_pool = Qnil;
2181
2309
  self->default_file_builder = Qnil;
2182
2310
  return ret;
2183
2311
  }
2184
2312
 
2185
- void Builder_register(VALUE module) {
2186
- VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
2187
- rb_define_alloc_func(klass, Builder_alloc);
2188
- rb_define_method(klass, "initialize", Builder_initialize, 1);
2189
- rb_define_method(klass, "add_file", Builder_add_file, -1);
2190
- rb_define_method(klass, "add_message", Builder_add_message, 1);
2191
- rb_define_method(klass, "add_enum", Builder_add_enum, 1);
2192
- rb_gc_register_address(&cBuilder);
2193
- cBuilder = klass;
2194
- }
2195
-
2196
2313
  /*
2197
2314
  * call-seq:
2198
2315
  * Builder.new(descriptor_pool) => builder
@@ -2201,8 +2318,8 @@ void Builder_register(VALUE module) {
2201
2318
  * descriptors and atomically register them into a pool in a way that allows for
2202
2319
  * (co)recursive type references.
2203
2320
  */
2204
- VALUE Builder_initialize(VALUE _self, VALUE pool) {
2205
- DEFINE_SELF(Builder, self, _self);
2321
+ static VALUE Builder_initialize(VALUE _self, VALUE pool) {
2322
+ Builder* self = ruby_to_Builder(_self);
2206
2323
  self->descriptor_pool = pool;
2207
2324
  self->default_file_builder = Qnil; // Created lazily if needed.
2208
2325
  return Qnil;
@@ -2219,8 +2336,8 @@ VALUE Builder_initialize(VALUE _self, VALUE pool) {
2219
2336
  *
2220
2337
  * This is the recommended, idiomatic way to build file descriptors.
2221
2338
  */
2222
- VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2223
- DEFINE_SELF(Builder, self, _self);
2339
+ static VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2340
+ Builder* self = ruby_to_Builder(_self);
2224
2341
  VALUE name, options;
2225
2342
  VALUE ctx;
2226
2343
  VALUE block;
@@ -2240,7 +2357,7 @@ VALUE Builder_add_file(int argc, VALUE* argv, VALUE _self) {
2240
2357
  }
2241
2358
 
2242
2359
  static VALUE Builder_get_default_file(VALUE _self) {
2243
- DEFINE_SELF(Builder, self, _self);
2360
+ Builder* self = ruby_to_Builder(_self);
2244
2361
 
2245
2362
  /* Lazily create only if legacy builder-level methods are called. */
2246
2363
  if (self->default_file_builder == Qnil) {
@@ -2264,7 +2381,7 @@ static VALUE Builder_get_default_file(VALUE _self) {
2264
2381
  * files generated by protoc which don't add messages within "add_file" block.
2265
2382
  * Descriptors created this way get assigned to a default empty FileDescriptor.
2266
2383
  */
2267
- VALUE Builder_add_message(VALUE _self, VALUE name) {
2384
+ static VALUE Builder_add_message(VALUE _self, VALUE name) {
2268
2385
  VALUE file_builder = Builder_get_default_file(_self);
2269
2386
  rb_funcall_with_block(file_builder, rb_intern("add_message"), 1, &name,
2270
2387
  rb_block_proc());
@@ -2283,7 +2400,7 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
2283
2400
  * Enum descriptors created this way get assigned to a default empty
2284
2401
  * FileDescriptor.
2285
2402
  */
2286
- VALUE Builder_add_enum(VALUE _self, VALUE name) {
2403
+ static VALUE Builder_add_enum(VALUE _self, VALUE name) {
2287
2404
  VALUE file_builder = Builder_get_default_file(_self);
2288
2405
  rb_funcall_with_block(file_builder, rb_intern("add_enum"), 1, &name,
2289
2406
  rb_block_proc());
@@ -2292,8 +2409,8 @@ VALUE Builder_add_enum(VALUE _self, VALUE name) {
2292
2409
 
2293
2410
  /* This method is hidden from Ruby, and only called directly from
2294
2411
  * DescriptorPool_build(). */
2295
- VALUE Builder_build(VALUE _self) {
2296
- DEFINE_SELF(Builder, self, _self);
2412
+ static VALUE Builder_build(VALUE _self) {
2413
+ Builder* self = ruby_to_Builder(_self);
2297
2414
 
2298
2415
  if (self->default_file_builder != Qnil) {
2299
2416
  FileBuilderContext_build(self->default_file_builder);
@@ -2303,8 +2420,19 @@ VALUE Builder_build(VALUE _self) {
2303
2420
  return Qnil;
2304
2421
  }
2305
2422
 
2423
+ static void Builder_register(VALUE module) {
2424
+ VALUE klass = rb_define_class_under(module, "Builder", rb_cObject);
2425
+ rb_define_alloc_func(klass, Builder_alloc);
2426
+ rb_define_method(klass, "initialize", Builder_initialize, 1);
2427
+ rb_define_method(klass, "add_file", Builder_add_file, -1);
2428
+ rb_define_method(klass, "add_message", Builder_add_message, 1);
2429
+ rb_define_method(klass, "add_enum", Builder_add_enum, 1);
2430
+ rb_gc_register_address(&cBuilder);
2431
+ cBuilder = klass;
2432
+ }
2433
+
2306
2434
  static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
2307
- DEFINE_SELF(DescriptorPool, descriptor_pool, _descriptor_pool);
2435
+ DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool);
2308
2436
  VALUE key = ULL2NUM((intptr_t)ptr);
2309
2437
  VALUE def;
2310
2438
 
@@ -2319,48 +2447,111 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
2319
2447
  VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
2320
2448
  def = rb_class_new_instance(3, args, klass);
2321
2449
  rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
2322
-
2323
- // For message defs, we now eagerly get/create descriptors for all
2324
- // submessages. We will need these anyway to parse or serialize this
2325
- // message type. But more importantly, we must do this now so that
2326
- // add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
2327
- // need to create a Ruby object or insert into a Ruby Hash. We need to
2328
- // avoid triggering GC, which can switch Ruby threads and re-enter our
2329
- // C extension from a different thread. This wreaks havoc on our state
2330
- // if we were in the middle of building handlers.
2331
- if (klass == cDescriptor) {
2332
- const upb_msgdef *m = ptr;
2333
- upb_msg_field_iter it;
2334
- for (upb_msg_field_begin(&it, m);
2335
- !upb_msg_field_done(&it);
2336
- upb_msg_field_next(&it)) {
2337
- const upb_fielddef* f = upb_msg_iter_field(&it);
2338
- if (upb_fielddef_issubmsg(f)) {
2339
- get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
2340
- }
2341
- }
2342
- }
2343
2450
  }
2344
2451
 
2345
2452
  return def;
2346
2453
  }
2347
2454
 
2348
- VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
2455
+ static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_msgdef* def) {
2349
2456
  return get_def_obj(descriptor_pool, def, cDescriptor);
2350
2457
  }
2351
2458
 
2352
- VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
2459
+ static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_enumdef* def) {
2353
2460
  return get_def_obj(descriptor_pool, def, cEnumDescriptor);
2354
2461
  }
2355
2462
 
2356
- VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
2463
+ static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_fielddef* def) {
2357
2464
  return get_def_obj(descriptor_pool, def, cFieldDescriptor);
2358
2465
  }
2359
2466
 
2360
- VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
2467
+ static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_filedef* def) {
2361
2468
  return get_def_obj(descriptor_pool, def, cFileDescriptor);
2362
2469
  }
2363
2470
 
2364
- VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
2471
+ static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_oneofdef* def) {
2365
2472
  return get_def_obj(descriptor_pool, def, cOneofDescriptor);
2366
2473
  }
2474
+
2475
+ // -----------------------------------------------------------------------------
2476
+ // Shared functions
2477
+ // -----------------------------------------------------------------------------
2478
+
2479
+ // Functions exposed to other modules in defs.h.
2480
+
2481
+ VALUE Descriptor_DefToClass(const upb_msgdef *m) {
2482
+ const upb_symtab *symtab = upb_filedef_symtab(upb_msgdef_file(m));
2483
+ VALUE pool = ObjectCache_Get(symtab);
2484
+ PBRUBY_ASSERT(pool != Qnil);
2485
+ VALUE desc_rb = get_msgdef_obj(pool, m);
2486
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
2487
+ return desc->klass;
2488
+ }
2489
+
2490
+ const upb_msgdef *Descriptor_GetMsgDef(VALUE desc_rb) {
2491
+ const Descriptor* desc = ruby_to_Descriptor(desc_rb);
2492
+ return desc->msgdef;
2493
+ }
2494
+
2495
+ VALUE TypeInfo_InitArg(int argc, VALUE *argv, int skip_arg) {
2496
+ if (argc > skip_arg) {
2497
+ if (argc > 1 + skip_arg) {
2498
+ rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", skip_arg + 1);
2499
+ }
2500
+ return argv[skip_arg];
2501
+ } else {
2502
+ return Qnil;
2503
+ }
2504
+ }
2505
+
2506
+ TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg,
2507
+ VALUE* type_class, VALUE* init_arg) {
2508
+ TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])};
2509
+
2510
+ if (ret.type == UPB_TYPE_MESSAGE || ret.type == UPB_TYPE_ENUM) {
2511
+ *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2);
2512
+
2513
+ if (argc < 2 + skip_arg) {
2514
+ rb_raise(rb_eArgError, "Expected at least %d arguments for message/enum.",
2515
+ 2 + skip_arg);
2516
+ }
2517
+
2518
+ VALUE klass = argv[1 + skip_arg];
2519
+ VALUE desc = MessageOrEnum_GetDescriptor(klass);
2520
+ *type_class = klass;
2521
+
2522
+ if (desc == Qnil) {
2523
+ rb_raise(rb_eArgError,
2524
+ "Type class has no descriptor. Please pass a "
2525
+ "class or enum as returned by the DescriptorPool.");
2526
+ }
2527
+
2528
+ if (ret.type == UPB_TYPE_MESSAGE) {
2529
+ ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef;
2530
+ Message_CheckClass(klass);
2531
+ } else {
2532
+ PBRUBY_ASSERT(ret.type == UPB_TYPE_ENUM);
2533
+ ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef;
2534
+ }
2535
+ } else {
2536
+ *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 1);
2537
+ }
2538
+
2539
+ return ret;
2540
+ }
2541
+
2542
+ void Defs_register(VALUE module) {
2543
+ DescriptorPool_register(module);
2544
+ Descriptor_register(module);
2545
+ FileDescriptor_register(module);
2546
+ FieldDescriptor_register(module);
2547
+ OneofDescriptor_register(module);
2548
+ EnumDescriptor_register(module);
2549
+ FileBuilderContext_register(module);
2550
+ MessageBuilderContext_register(module);
2551
+ OneofBuilderContext_register(module);
2552
+ EnumBuilderContext_register(module);
2553
+ Builder_register(module);
2554
+
2555
+ rb_gc_register_address(&c_only_cookie);
2556
+ c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject);
2557
+ }