• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 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 __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
32 #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
33 
34 #include <ruby/ruby.h>
35 #include <ruby/vm.h>
36 #include <ruby/encoding.h>
37 
38 #include "upb.h"
39 
40 // Forward decls.
41 struct DescriptorPool;
42 struct Descriptor;
43 struct FieldDescriptor;
44 struct EnumDescriptor;
45 struct MessageLayout;
46 struct MessageField;
47 struct MessageHeader;
48 struct MessageBuilderContext;
49 struct EnumBuilderContext;
50 struct Builder;
51 
52 typedef struct DescriptorPool DescriptorPool;
53 typedef struct Descriptor Descriptor;
54 typedef struct FieldDescriptor FieldDescriptor;
55 typedef struct OneofDescriptor OneofDescriptor;
56 typedef struct EnumDescriptor EnumDescriptor;
57 typedef struct MessageLayout MessageLayout;
58 typedef struct MessageField MessageField;
59 typedef struct MessageHeader MessageHeader;
60 typedef struct MessageBuilderContext MessageBuilderContext;
61 typedef struct OneofBuilderContext OneofBuilderContext;
62 typedef struct EnumBuilderContext EnumBuilderContext;
63 typedef struct Builder Builder;
64 
65 /*
66  It can be a bit confusing how the C structs defined below and the Ruby
67  objects interact and hold references to each other. First, a few principles:
68 
69  - Ruby's "TypedData" abstraction lets a Ruby VALUE hold a pointer to a C
70    struct (or arbitrary memory chunk), own it, and free it when collected.
71    Thus, each struct below will have a corresponding Ruby object
72    wrapping/owning it.
73 
74  - To get back from an underlying upb {msg,enum}def to the Ruby object, we
75    keep a global hashmap, accessed by get_def_obj/add_def_obj below.
76 
77  The in-memory structure is then something like:
78 
79    Ruby                        |      upb
80                                |
81    DescriptorPool  ------------|-----------> upb_symtab____________________
82                                |                | (message types)          \
83                                |                v                           \
84    Descriptor   ---------------|-----------> upb_msgdef         (enum types)|
85     |--> msgclass              |                |   ^                       |
86     |    (dynamically built)   |                |   | (submsg fields)       |
87     |--> MessageLayout         |                |   |                       /
88     |--------------------------|> decoder method|   |                      /
89     \--------------------------|> serialize     |   |                     /
90                                |  handlers      v   |                    /
91    FieldDescriptor  -----------|-----------> upb_fielddef               /
92                                |                    |                  /
93                                |                    v (enum fields)   /
94    EnumDescriptor  ------------|-----------> upb_enumdef  <----------'
95                                |
96                                |
97                ^               |               \___/
98                `---------------|-----------------'    (get_def_obj map)
99  */
100 
101 // -----------------------------------------------------------------------------
102 // Ruby class structure definitions.
103 // -----------------------------------------------------------------------------
104 
105 struct DescriptorPool {
106   upb_symtab* symtab;
107 };
108 
109 struct Descriptor {
110   const upb_msgdef* msgdef;
111   MessageLayout* layout;
112   VALUE klass;  // begins as nil
113   const upb_handlers* fill_handlers;
114   const upb_pbdecodermethod* fill_method;
115   const upb_json_parsermethod* json_fill_method;
116   const upb_handlers* pb_serialize_handlers;
117   const upb_handlers* json_serialize_handlers;
118   const upb_handlers* json_serialize_handlers_preserve;
119   // Handlers hold type class references for sub-message fields directly in some
120   // cases. We need to keep these rooted because they might otherwise be
121   // collected.
122   VALUE typeclass_references;
123 };
124 
125 struct FieldDescriptor {
126   const upb_fielddef* fielddef;
127 };
128 
129 struct OneofDescriptor {
130   const upb_oneofdef* oneofdef;
131 };
132 
133 struct EnumDescriptor {
134   const upb_enumdef* enumdef;
135   VALUE module;  // begins as nil
136 };
137 
138 struct MessageBuilderContext {
139   VALUE descriptor;
140   VALUE builder;
141 };
142 
143 struct OneofBuilderContext {
144   VALUE descriptor;
145   VALUE builder;
146 };
147 
148 struct EnumBuilderContext {
149   VALUE enumdesc;
150 };
151 
152 struct Builder {
153   VALUE pending_list;
154   upb_def** defs;  // used only while finalizing
155 };
156 
157 extern VALUE cDescriptorPool;
158 extern VALUE cDescriptor;
159 extern VALUE cFieldDescriptor;
160 extern VALUE cEnumDescriptor;
161 extern VALUE cMessageBuilderContext;
162 extern VALUE cOneofBuilderContext;
163 extern VALUE cEnumBuilderContext;
164 extern VALUE cBuilder;
165 
166 extern VALUE cError;
167 extern VALUE cParseError;
168 
169 // We forward-declare all of the Ruby method implementations here because we
170 // sometimes call the methods directly across .c files, rather than going
171 // through Ruby's method dispatching (e.g. during message parse). It's cleaner
172 // to keep the list of object methods together than to split them between
173 // static-in-file definitions and header declarations.
174 
175 void DescriptorPool_mark(void* _self);
176 void DescriptorPool_free(void* _self);
177 VALUE DescriptorPool_alloc(VALUE klass);
178 void DescriptorPool_register(VALUE module);
179 DescriptorPool* ruby_to_DescriptorPool(VALUE value);
180 VALUE DescriptorPool_add(VALUE _self, VALUE def);
181 VALUE DescriptorPool_build(VALUE _self);
182 VALUE DescriptorPool_lookup(VALUE _self, VALUE name);
183 VALUE DescriptorPool_generated_pool(VALUE _self);
184 
185 void Descriptor_mark(void* _self);
186 void Descriptor_free(void* _self);
187 VALUE Descriptor_alloc(VALUE klass);
188 void Descriptor_register(VALUE module);
189 Descriptor* ruby_to_Descriptor(VALUE value);
190 VALUE Descriptor_name(VALUE _self);
191 VALUE Descriptor_name_set(VALUE _self, VALUE str);
192 VALUE Descriptor_each(VALUE _self);
193 VALUE Descriptor_lookup(VALUE _self, VALUE name);
194 VALUE Descriptor_add_field(VALUE _self, VALUE obj);
195 VALUE Descriptor_add_oneof(VALUE _self, VALUE obj);
196 VALUE Descriptor_each_oneof(VALUE _self);
197 VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name);
198 VALUE Descriptor_msgclass(VALUE _self);
199 extern const rb_data_type_t _Descriptor_type;
200 
201 void FieldDescriptor_mark(void* _self);
202 void FieldDescriptor_free(void* _self);
203 VALUE FieldDescriptor_alloc(VALUE klass);
204 void FieldDescriptor_register(VALUE module);
205 FieldDescriptor* ruby_to_FieldDescriptor(VALUE value);
206 VALUE FieldDescriptor_name(VALUE _self);
207 VALUE FieldDescriptor_name_set(VALUE _self, VALUE str);
208 VALUE FieldDescriptor_type(VALUE _self);
209 VALUE FieldDescriptor_type_set(VALUE _self, VALUE type);
210 VALUE FieldDescriptor_label(VALUE _self);
211 VALUE FieldDescriptor_label_set(VALUE _self, VALUE label);
212 VALUE FieldDescriptor_number(VALUE _self);
213 VALUE FieldDescriptor_number_set(VALUE _self, VALUE number);
214 VALUE FieldDescriptor_submsg_name(VALUE _self);
215 VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value);
216 VALUE FieldDescriptor_subtype(VALUE _self);
217 VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb);
218 VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value);
219 upb_fieldtype_t ruby_to_fieldtype(VALUE type);
220 VALUE fieldtype_to_ruby(upb_fieldtype_t type);
221 
222 void OneofDescriptor_mark(void* _self);
223 void OneofDescriptor_free(void* _self);
224 VALUE OneofDescriptor_alloc(VALUE klass);
225 void OneofDescriptor_register(VALUE module);
226 OneofDescriptor* ruby_to_OneofDescriptor(VALUE value);
227 VALUE OneofDescriptor_name(VALUE _self);
228 VALUE OneofDescriptor_name_set(VALUE _self, VALUE value);
229 VALUE OneofDescriptor_add_field(VALUE _self, VALUE field);
230 VALUE OneofDescriptor_each(VALUE _self, VALUE field);
231 
232 void EnumDescriptor_mark(void* _self);
233 void EnumDescriptor_free(void* _self);
234 VALUE EnumDescriptor_alloc(VALUE klass);
235 void EnumDescriptor_register(VALUE module);
236 EnumDescriptor* ruby_to_EnumDescriptor(VALUE value);
237 VALUE EnumDescriptor_name(VALUE _self);
238 VALUE EnumDescriptor_name_set(VALUE _self, VALUE str);
239 VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number);
240 VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name);
241 VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number);
242 VALUE EnumDescriptor_each(VALUE _self);
243 VALUE EnumDescriptor_enummodule(VALUE _self);
244 extern const rb_data_type_t _EnumDescriptor_type;
245 
246 void MessageBuilderContext_mark(void* _self);
247 void MessageBuilderContext_free(void* _self);
248 VALUE MessageBuilderContext_alloc(VALUE klass);
249 void MessageBuilderContext_register(VALUE module);
250 MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE value);
251 VALUE MessageBuilderContext_initialize(VALUE _self,
252                                        VALUE descriptor,
253                                        VALUE builder);
254 VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self);
255 VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self);
256 VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self);
257 VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self);
258 VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name);
259 
260 void OneofBuilderContext_mark(void* _self);
261 void OneofBuilderContext_free(void* _self);
262 VALUE OneofBuilderContext_alloc(VALUE klass);
263 void OneofBuilderContext_register(VALUE module);
264 OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE value);
265 VALUE OneofBuilderContext_initialize(VALUE _self,
266                                      VALUE descriptor,
267                                      VALUE builder);
268 VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self);
269 
270 void EnumBuilderContext_mark(void* _self);
271 void EnumBuilderContext_free(void* _self);
272 VALUE EnumBuilderContext_alloc(VALUE klass);
273 void EnumBuilderContext_register(VALUE module);
274 EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE value);
275 VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdesc);
276 VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number);
277 
278 void Builder_mark(void* _self);
279 void Builder_free(void* _self);
280 VALUE Builder_alloc(VALUE klass);
281 void Builder_register(VALUE module);
282 Builder* ruby_to_Builder(VALUE value);
283 VALUE Builder_add_message(VALUE _self, VALUE name);
284 VALUE Builder_add_enum(VALUE _self, VALUE name);
285 VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb);
286 
287 // -----------------------------------------------------------------------------
288 // Native slot storage abstraction.
289 // -----------------------------------------------------------------------------
290 
291 #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
292 
293 size_t native_slot_size(upb_fieldtype_t type);
294 void native_slot_set(upb_fieldtype_t type,
295                      VALUE type_class,
296                      void* memory,
297                      VALUE value);
298 // Atomically (with respect to Ruby VM calls) either update the value and set a
299 // oneof case, or do neither. If |case_memory| is null, then no case value is
300 // set.
301 void native_slot_set_value_and_case(upb_fieldtype_t type,
302                                     VALUE type_class,
303                                     void* memory,
304                                     VALUE value,
305                                     uint32_t* case_memory,
306                                     uint32_t case_number);
307 VALUE native_slot_get(upb_fieldtype_t type,
308                       VALUE type_class,
309                       const void* memory);
310 void native_slot_init(upb_fieldtype_t type, void* memory);
311 void native_slot_mark(upb_fieldtype_t type, void* memory);
312 void native_slot_dup(upb_fieldtype_t type, void* to, void* from);
313 void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from);
314 bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
315 
316 void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value);
317 void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value);
318 
319 extern rb_encoding* kRubyStringUtf8Encoding;
320 extern rb_encoding* kRubyStringASCIIEncoding;
321 extern rb_encoding* kRubyString8bitEncoding;
322 
323 VALUE field_type_class(const upb_fielddef* field);
324 
325 #define MAP_KEY_FIELD 1
326 #define MAP_VALUE_FIELD 2
327 
328 // Oneof case slot value to indicate that no oneof case is set. The value `0` is
329 // safe because field numbers are used as case identifiers, and no field can
330 // have a number of 0.
331 #define ONEOF_CASE_NONE 0
332 
333 // These operate on a map field (i.e., a repeated field of submessages whose
334 // submessage type is a map-entry msgdef).
335 bool is_map_field(const upb_fielddef* field);
336 const upb_fielddef* map_field_key(const upb_fielddef* field);
337 const upb_fielddef* map_field_value(const upb_fielddef* field);
338 
339 // These operate on a map-entry msgdef.
340 const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
341 const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
342 
343 // -----------------------------------------------------------------------------
344 // Repeated field container type.
345 // -----------------------------------------------------------------------------
346 
347 typedef struct {
348   upb_fieldtype_t field_type;
349   VALUE field_type_class;
350   void* elements;
351   int size;
352   int capacity;
353 } RepeatedField;
354 
355 void RepeatedField_mark(void* self);
356 void RepeatedField_free(void* self);
357 VALUE RepeatedField_alloc(VALUE klass);
358 VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self);
359 void RepeatedField_register(VALUE module);
360 
361 extern const rb_data_type_t RepeatedField_type;
362 extern VALUE cRepeatedField;
363 
364 RepeatedField* ruby_to_RepeatedField(VALUE value);
365 
366 VALUE RepeatedField_each(VALUE _self);
367 VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self);
368 void* RepeatedField_index_native(VALUE _self, int index);
369 VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val);
370 void RepeatedField_reserve(RepeatedField* self, int new_size);
371 VALUE RepeatedField_push(VALUE _self, VALUE val);
372 void RepeatedField_push_native(VALUE _self, void* data);
373 VALUE RepeatedField_pop_one(VALUE _self);
374 VALUE RepeatedField_insert(int argc, VALUE* argv, VALUE _self);
375 VALUE RepeatedField_replace(VALUE _self, VALUE list);
376 VALUE RepeatedField_clear(VALUE _self);
377 VALUE RepeatedField_length(VALUE _self);
378 VALUE RepeatedField_dup(VALUE _self);
379 VALUE RepeatedField_deep_copy(VALUE _self);
380 VALUE RepeatedField_to_ary(VALUE _self);
381 VALUE RepeatedField_eq(VALUE _self, VALUE _other);
382 VALUE RepeatedField_hash(VALUE _self);
383 VALUE RepeatedField_inspect(VALUE _self);
384 VALUE RepeatedField_plus(VALUE _self, VALUE list);
385 
386 // Defined in repeated_field.c; also used by Map.
387 void validate_type_class(upb_fieldtype_t type, VALUE klass);
388 
389 // -----------------------------------------------------------------------------
390 // Map container type.
391 // -----------------------------------------------------------------------------
392 
393 typedef struct {
394   upb_fieldtype_t key_type;
395   upb_fieldtype_t value_type;
396   VALUE value_type_class;
397   upb_strtable table;
398 } Map;
399 
400 void Map_mark(void* self);
401 void Map_free(void* self);
402 VALUE Map_alloc(VALUE klass);
403 VALUE Map_init(int argc, VALUE* argv, VALUE self);
404 void Map_register(VALUE module);
405 
406 extern const rb_data_type_t Map_type;
407 extern VALUE cMap;
408 
409 Map* ruby_to_Map(VALUE value);
410 
411 VALUE Map_each(VALUE _self);
412 VALUE Map_keys(VALUE _self);
413 VALUE Map_values(VALUE _self);
414 VALUE Map_index(VALUE _self, VALUE key);
415 VALUE Map_index_set(VALUE _self, VALUE key, VALUE value);
416 VALUE Map_has_key(VALUE _self, VALUE key);
417 VALUE Map_delete(VALUE _self, VALUE key);
418 VALUE Map_clear(VALUE _self);
419 VALUE Map_length(VALUE _self);
420 VALUE Map_dup(VALUE _self);
421 VALUE Map_deep_copy(VALUE _self);
422 VALUE Map_eq(VALUE _self, VALUE _other);
423 VALUE Map_hash(VALUE _self);
424 VALUE Map_inspect(VALUE _self);
425 VALUE Map_merge(VALUE _self, VALUE hashmap);
426 VALUE Map_merge_into_self(VALUE _self, VALUE hashmap);
427 
428 typedef struct {
429   Map* self;
430   upb_strtable_iter it;
431 } Map_iter;
432 
433 void Map_begin(VALUE _self, Map_iter* iter);
434 void Map_next(Map_iter* iter);
435 bool Map_done(Map_iter* iter);
436 VALUE Map_iter_key(Map_iter* iter);
437 VALUE Map_iter_value(Map_iter* iter);
438 
439 // -----------------------------------------------------------------------------
440 // Message layout / storage.
441 // -----------------------------------------------------------------------------
442 
443 #define MESSAGE_FIELD_NO_CASE ((size_t)-1)
444 
445 struct MessageField {
446   size_t offset;
447   size_t case_offset;  // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
448 };
449 
450 struct MessageLayout {
451   const upb_msgdef* msgdef;
452   MessageField* fields;
453   size_t size;
454 };
455 
456 MessageLayout* create_layout(const upb_msgdef* msgdef);
457 void free_layout(MessageLayout* layout);
458 VALUE layout_get(MessageLayout* layout,
459                  const void* storage,
460                  const upb_fielddef* field);
461 void layout_set(MessageLayout* layout,
462                 void* storage,
463                 const upb_fielddef* field,
464                 VALUE val);
465 void layout_init(MessageLayout* layout, void* storage);
466 void layout_mark(MessageLayout* layout, void* storage);
467 void layout_dup(MessageLayout* layout, void* to, void* from);
468 void layout_deep_copy(MessageLayout* layout, void* to, void* from);
469 VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2);
470 VALUE layout_hash(MessageLayout* layout, void* storage);
471 VALUE layout_inspect(MessageLayout* layout, void* storage);
472 
473 // -----------------------------------------------------------------------------
474 // Message class creation.
475 // -----------------------------------------------------------------------------
476 
477 struct MessageHeader {
478   Descriptor* descriptor;  // kept alive by self.class.descriptor reference.
479   // Data comes after this.
480 };
481 
482 extern rb_data_type_t Message_type;
483 
484 VALUE build_class_from_descriptor(Descriptor* descriptor);
485 void* Message_data(void* msg);
486 void Message_mark(void* self);
487 void Message_free(void* self);
488 VALUE Message_alloc(VALUE klass);
489 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self);
490 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self);
491 VALUE Message_dup(VALUE _self);
492 VALUE Message_deep_copy(VALUE _self);
493 VALUE Message_eq(VALUE _self, VALUE _other);
494 VALUE Message_hash(VALUE _self);
495 VALUE Message_inspect(VALUE _self);
496 VALUE Message_index(VALUE _self, VALUE field_name);
497 VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value);
498 VALUE Message_descriptor(VALUE klass);
499 VALUE Message_decode(VALUE klass, VALUE data);
500 VALUE Message_encode(VALUE klass, VALUE msg_rb);
501 VALUE Message_decode_json(VALUE klass, VALUE data);
502 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
503 
504 VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj);
505 
506 VALUE build_module_from_enumdesc(EnumDescriptor* enumdef);
507 VALUE enum_lookup(VALUE self, VALUE number);
508 VALUE enum_resolve(VALUE self, VALUE sym);
509 
510 const upb_pbdecodermethod *new_fillmsg_decodermethod(
511     Descriptor* descriptor, const void *owner);
512 
513 // Maximum depth allowed during encoding, to avoid stack overflows due to
514 // cycles.
515 #define ENCODE_MAX_NESTING 63
516 
517 // -----------------------------------------------------------------------------
518 // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
519 // instances.
520 // -----------------------------------------------------------------------------
521 void add_def_obj(const void* def, VALUE value);
522 VALUE get_def_obj(const void* def);
523 
524 // -----------------------------------------------------------------------------
525 // Utilities.
526 // -----------------------------------------------------------------------------
527 
528 void check_upb_status(const upb_status* status, const char* msg);
529 
530 #define CHECK_UPB(code, msg) do {                                             \
531     upb_status status = UPB_STATUS_INIT;                                      \
532     code;                                                                     \
533     check_upb_status(&status, msg);                                           \
534 } while (0)
535 
536 extern ID descriptor_instancevar_interned;
537 
538 #endif  // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
539