google-protobuf 3.6.1 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

@@ -41,6 +41,7 @@ VALUE upb_def_to_ruby_obj_map;
41
41
 
42
42
  VALUE cError;
43
43
  VALUE cParseError;
44
+ VALUE cTypeError;
44
45
 
45
46
  void add_def_obj(const void* def, VALUE value) {
46
47
  rb_hash_aset(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def), value);
@@ -90,18 +91,21 @@ void Init_protobuf_c() {
90
91
  descriptor_instancevar_interned = rb_intern(kDescriptorInstanceVar);
91
92
  DescriptorPool_register(protobuf);
92
93
  Descriptor_register(protobuf);
94
+ FileDescriptor_register(protobuf);
93
95
  FieldDescriptor_register(protobuf);
94
96
  OneofDescriptor_register(protobuf);
95
97
  EnumDescriptor_register(protobuf);
96
98
  MessageBuilderContext_register(internal);
97
99
  OneofBuilderContext_register(internal);
98
100
  EnumBuilderContext_register(internal);
101
+ FileBuilderContext_register(internal);
99
102
  Builder_register(internal);
100
103
  RepeatedField_register(protobuf);
101
104
  Map_register(protobuf);
102
105
 
103
106
  cError = rb_const_get(protobuf, rb_intern("Error"));
104
107
  cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
108
+ cTypeError = rb_const_get(protobuf, rb_intern("TypeError"));
105
109
 
106
110
  rb_define_singleton_method(protobuf, "discard_unknown",
107
111
  Google_Protobuf_discard_unknown, 1);
@@ -40,6 +40,7 @@
40
40
  // Forward decls.
41
41
  struct DescriptorPool;
42
42
  struct Descriptor;
43
+ struct FileDescriptor;
43
44
  struct FieldDescriptor;
44
45
  struct EnumDescriptor;
45
46
  struct MessageLayout;
@@ -47,10 +48,12 @@ struct MessageField;
47
48
  struct MessageHeader;
48
49
  struct MessageBuilderContext;
49
50
  struct EnumBuilderContext;
51
+ struct FileBuilderContext;
50
52
  struct Builder;
51
53
 
52
54
  typedef struct DescriptorPool DescriptorPool;
53
55
  typedef struct Descriptor Descriptor;
56
+ typedef struct FileDescriptor FileDescriptor;
54
57
  typedef struct FieldDescriptor FieldDescriptor;
55
58
  typedef struct OneofDescriptor OneofDescriptor;
56
59
  typedef struct EnumDescriptor EnumDescriptor;
@@ -60,6 +63,7 @@ typedef struct MessageHeader MessageHeader;
60
63
  typedef struct MessageBuilderContext MessageBuilderContext;
61
64
  typedef struct OneofBuilderContext OneofBuilderContext;
62
65
  typedef struct EnumBuilderContext EnumBuilderContext;
66
+ typedef struct FileBuilderContext FileBuilderContext;
63
67
  typedef struct Builder Builder;
64
68
 
65
69
  /*
@@ -118,6 +122,10 @@ struct Descriptor {
118
122
  const upb_handlers* json_serialize_handlers_preserve;
119
123
  };
120
124
 
125
+ struct FileDescriptor {
126
+ const upb_filedef* filedef;
127
+ };
128
+
121
129
  struct FieldDescriptor {
122
130
  const upb_fielddef* fielddef;
123
131
  };
@@ -145,22 +153,32 @@ struct EnumBuilderContext {
145
153
  VALUE enumdesc;
146
154
  };
147
155
 
156
+ struct FileBuilderContext {
157
+ VALUE pending_list;
158
+ VALUE file_descriptor;
159
+ VALUE builder;
160
+ };
161
+
148
162
  struct Builder {
149
163
  VALUE pending_list;
164
+ VALUE default_file_descriptor;
150
165
  upb_def** defs; // used only while finalizing
151
166
  };
152
167
 
153
168
  extern VALUE cDescriptorPool;
154
169
  extern VALUE cDescriptor;
170
+ extern VALUE cFileDescriptor;
155
171
  extern VALUE cFieldDescriptor;
156
172
  extern VALUE cEnumDescriptor;
157
173
  extern VALUE cMessageBuilderContext;
158
174
  extern VALUE cOneofBuilderContext;
159
175
  extern VALUE cEnumBuilderContext;
176
+ extern VALUE cFileBuilderContext;
160
177
  extern VALUE cBuilder;
161
178
 
162
179
  extern VALUE cError;
163
180
  extern VALUE cParseError;
181
+ extern VALUE cTypeError;
164
182
 
165
183
  // We forward-declare all of the Ruby method implementations here because we
166
184
  // sometimes call the methods directly across .c files, rather than going
@@ -174,15 +192,18 @@ VALUE DescriptorPool_alloc(VALUE klass);
174
192
  void DescriptorPool_register(VALUE module);
175
193
  DescriptorPool* ruby_to_DescriptorPool(VALUE value);
176
194
  VALUE DescriptorPool_add(VALUE _self, VALUE def);
177
- VALUE DescriptorPool_build(VALUE _self);
195
+ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self);
178
196
  VALUE DescriptorPool_lookup(VALUE _self, VALUE name);
179
197
  VALUE DescriptorPool_generated_pool(VALUE _self);
180
198
 
199
+ extern VALUE generated_pool;
200
+
181
201
  void Descriptor_mark(void* _self);
182
202
  void Descriptor_free(void* _self);
183
203
  VALUE Descriptor_alloc(VALUE klass);
184
204
  void Descriptor_register(VALUE module);
185
205
  Descriptor* ruby_to_Descriptor(VALUE value);
206
+ VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb);
186
207
  VALUE Descriptor_name(VALUE _self);
187
208
  VALUE Descriptor_name_set(VALUE _self, VALUE str);
188
209
  VALUE Descriptor_each(VALUE _self);
@@ -192,8 +213,19 @@ VALUE Descriptor_add_oneof(VALUE _self, VALUE obj);
192
213
  VALUE Descriptor_each_oneof(VALUE _self);
193
214
  VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name);
194
215
  VALUE Descriptor_msgclass(VALUE _self);
216
+ VALUE Descriptor_file_descriptor(VALUE _self);
195
217
  extern const rb_data_type_t _Descriptor_type;
196
218
 
219
+ void FileDescriptor_mark(void* _self);
220
+ void FileDescriptor_free(void* _self);
221
+ VALUE FileDescriptor_alloc(VALUE klass);
222
+ void FileDescriptor_register(VALUE module);
223
+ FileDescriptor* ruby_to_FileDescriptor(VALUE value);
224
+ VALUE FileDescriptor_initialize(int argc, VALUE* argv, VALUE _self);
225
+ VALUE FileDescriptor_name(VALUE _self);
226
+ VALUE FileDescriptor_syntax(VALUE _self);
227
+ VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax);
228
+
197
229
  void FieldDescriptor_mark(void* _self);
198
230
  void FieldDescriptor_free(void* _self);
199
231
  VALUE FieldDescriptor_alloc(VALUE klass);
@@ -203,6 +235,8 @@ VALUE FieldDescriptor_name(VALUE _self);
203
235
  VALUE FieldDescriptor_name_set(VALUE _self, VALUE str);
204
236
  VALUE FieldDescriptor_type(VALUE _self);
205
237
  VALUE FieldDescriptor_type_set(VALUE _self, VALUE type);
238
+ VALUE FieldDescriptor_default(VALUE _self);
239
+ VALUE FieldDescriptor_default_set(VALUE _self, VALUE default_value);
206
240
  VALUE FieldDescriptor_label(VALUE _self);
207
241
  VALUE FieldDescriptor_label_set(VALUE _self, VALUE label);
208
242
  VALUE FieldDescriptor_number(VALUE _self);
@@ -210,6 +244,8 @@ VALUE FieldDescriptor_number_set(VALUE _self, VALUE number);
210
244
  VALUE FieldDescriptor_submsg_name(VALUE _self);
211
245
  VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value);
212
246
  VALUE FieldDescriptor_subtype(VALUE _self);
247
+ VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb);
248
+ VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb);
213
249
  VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb);
214
250
  VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value);
215
251
  upb_fieldtype_t ruby_to_fieldtype(VALUE type);
@@ -230,6 +266,8 @@ void EnumDescriptor_free(void* _self);
230
266
  VALUE EnumDescriptor_alloc(VALUE klass);
231
267
  void EnumDescriptor_register(VALUE module);
232
268
  EnumDescriptor* ruby_to_EnumDescriptor(VALUE value);
269
+ VALUE EnumDescriptor_initialize(VALUE _self, VALUE file_descriptor_rb);
270
+ VALUE EnumDescriptor_file_descriptor(VALUE _self);
233
271
  VALUE EnumDescriptor_name(VALUE _self);
234
272
  VALUE EnumDescriptor_name_set(VALUE _self, VALUE str);
235
273
  VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number);
@@ -271,12 +309,23 @@ EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE value);
271
309
  VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdesc);
272
310
  VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number);
273
311
 
312
+ void FileBuilderContext_mark(void* _self);
313
+ void FileBuilderContext_free(void* _self);
314
+ VALUE FileBuilderContext_alloc(VALUE klass);
315
+ void FileBuilderContext_register(VALUE module);
316
+ VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor,
317
+ VALUE builder);
318
+ VALUE FileBuilderContext_add_message(VALUE _self, VALUE name);
319
+ VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name);
320
+ VALUE FileBuilderContext_pending_descriptors(VALUE _self);
321
+
274
322
  void Builder_mark(void* _self);
275
323
  void Builder_free(void* _self);
276
324
  VALUE Builder_alloc(VALUE klass);
277
325
  void Builder_register(VALUE module);
278
326
  Builder* ruby_to_Builder(VALUE value);
279
327
  VALUE Builder_initialize(VALUE _self);
328
+ VALUE Builder_add_file(int argc, VALUE *argv, VALUE _self);
280
329
  VALUE Builder_add_message(VALUE _self, VALUE name);
281
330
  VALUE Builder_add_enum(VALUE _self, VALUE name);
282
331
  VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb);
@@ -288,14 +337,16 @@ VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb);
288
337
  #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
289
338
 
290
339
  size_t native_slot_size(upb_fieldtype_t type);
291
- void native_slot_set(upb_fieldtype_t type,
340
+ void native_slot_set(const char* name,
341
+ upb_fieldtype_t type,
292
342
  VALUE type_class,
293
343
  void* memory,
294
344
  VALUE value);
295
345
  // Atomically (with respect to Ruby VM calls) either update the value and set a
296
346
  // oneof case, or do neither. If |case_memory| is null, then no case value is
297
347
  // set.
298
- void native_slot_set_value_and_case(upb_fieldtype_t type,
348
+ void native_slot_set_value_and_case(const char* name,
349
+ upb_fieldtype_t type,
299
350
  VALUE type_class,
300
351
  void* memory,
301
352
  VALUE value,
@@ -311,7 +362,7 @@ void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from);
311
362
  bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
312
363
 
313
364
  VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value);
314
- void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value);
365
+ void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value);
315
366
 
316
367
  extern rb_encoding* kRubyStringUtf8Encoding;
317
368
  extern rb_encoding* kRubyStringASCIIEncoding;
@@ -442,10 +493,12 @@ VALUE Map_iter_value(Map_iter* iter);
442
493
  // -----------------------------------------------------------------------------
443
494
 
444
495
  #define MESSAGE_FIELD_NO_CASE ((size_t)-1)
496
+ #define MESSAGE_FIELD_NO_HASBIT ((size_t)-1)
445
497
 
446
498
  struct MessageField {
447
499
  size_t offset;
448
500
  size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
501
+ size_t hasbit;
449
502
  };
450
503
 
451
504
  struct MessageLayout {
@@ -456,6 +509,9 @@ struct MessageLayout {
456
509
 
457
510
  MessageLayout* create_layout(const upb_msgdef* msgdef);
458
511
  void free_layout(MessageLayout* layout);
512
+ bool field_contains_hasbit(MessageLayout* layout,
513
+ const upb_fielddef* field);
514
+ VALUE layout_get_default(const upb_fielddef* field);
459
515
  VALUE layout_get(MessageLayout* layout,
460
516
  const void* storage,
461
517
  const upb_fielddef* field);
@@ -463,6 +519,12 @@ void layout_set(MessageLayout* layout,
463
519
  void* storage,
464
520
  const upb_fielddef* field,
465
521
  VALUE val);
522
+ VALUE layout_has(MessageLayout* layout,
523
+ const void* storage,
524
+ const upb_fielddef* field);
525
+ void layout_clear(MessageLayout* layout,
526
+ const void* storage,
527
+ const upb_fielddef* field);
466
528
  void layout_init(MessageLayout* layout, void* storage);
467
529
  void layout_mark(MessageLayout* layout, void* storage);
468
530
  void layout_dup(MessageLayout* layout, void* to, void* from);
@@ -512,7 +574,7 @@ VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value);
512
574
  VALUE Message_descriptor(VALUE klass);
513
575
  VALUE Message_decode(VALUE klass, VALUE data);
514
576
  VALUE Message_encode(VALUE klass, VALUE msg_rb);
515
- VALUE Message_decode_json(VALUE klass, VALUE data);
577
+ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass);
516
578
  VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
517
579
 
518
580
  VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb);
@@ -178,7 +178,7 @@ VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
178
178
  }
179
179
 
180
180
  memory = RepeatedField_memoryat(self, index, element_size);
181
- native_slot_set(field_type, field_type_class, memory, val);
181
+ native_slot_set("", field_type, field_type_class, memory, val);
182
182
  return Qnil;
183
183
  }
184
184
 
@@ -217,12 +217,18 @@ VALUE RepeatedField_push(VALUE _self, VALUE val) {
217
217
 
218
218
  RepeatedField_reserve(self, self->size + 1);
219
219
  memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
220
- native_slot_set(field_type, self->field_type_class, memory, val);
220
+ native_slot_set("", field_type, self->field_type_class, memory, val);
221
221
  // native_slot_set may raise an error; bump size only after set.
222
222
  self->size++;
223
223
  return _self;
224
224
  }
225
225
 
226
+ VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
227
+ for (int i = 0; i < RARRAY_LEN(args); i++) {
228
+ RepeatedField_push(_self, rb_ary_entry(args, i));
229
+ }
230
+ return _self;
231
+ }
226
232
 
227
233
  // Used by parsing handlers.
228
234
  void RepeatedField_push_native(VALUE _self, void* data) {
@@ -635,7 +641,7 @@ void RepeatedField_register(VALUE module) {
635
641
  rb_define_method(klass, "[]", RepeatedField_index, -1);
636
642
  rb_define_method(klass, "at", RepeatedField_index, -1);
637
643
  rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
638
- rb_define_method(klass, "push", RepeatedField_push, 1);
644
+ rb_define_method(klass, "push", RepeatedField_push_vararg, -2);
639
645
  rb_define_method(klass, "<<", RepeatedField_push, 1);
640
646
  rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
641
647
  rb_define_method(klass, "replace", RepeatedField_replace, 1);
@@ -38,6 +38,8 @@
38
38
  // Ruby <-> native slot management.
39
39
  // -----------------------------------------------------------------------------
40
40
 
41
+ #define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
42
+ #define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
41
43
  #define DEREF(memory, type) *(type*)(memory)
42
44
 
43
45
  size_t native_slot_size(upb_fieldtype_t type) {
@@ -57,46 +59,16 @@ size_t native_slot_size(upb_fieldtype_t type) {
57
59
  }
58
60
  }
59
61
 
60
- static VALUE value_from_default(const upb_fielddef *field) {
61
- switch (upb_fielddef_type(field)) {
62
- case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
63
- case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
64
- case UPB_TYPE_BOOL:
65
- return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
66
- case UPB_TYPE_MESSAGE: return Qnil;
67
- case UPB_TYPE_ENUM: {
68
- const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
69
- int32_t num = upb_fielddef_defaultint32(field);
70
- const char *label = upb_enumdef_iton(enumdef, num);
71
- if (label) {
72
- return ID2SYM(rb_intern(label));
73
- } else {
74
- return INT2NUM(num);
75
- }
76
- }
77
- case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
78
- case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
79
- case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
80
- case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
81
- case UPB_TYPE_STRING:
82
- case UPB_TYPE_BYTES: {
83
- size_t size;
84
- const char *str = upb_fielddef_defaultstr(field, &size);
85
- return rb_str_new(str, size);
86
- }
87
- default: return Qnil;
88
- }
89
- }
90
-
91
62
  static bool is_ruby_num(VALUE value) {
92
63
  return (TYPE(value) == T_FLOAT ||
93
64
  TYPE(value) == T_FIXNUM ||
94
65
  TYPE(value) == T_BIGNUM);
95
66
  }
96
67
 
97
- void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
68
+ void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE val) {
98
69
  if (!is_ruby_num(val)) {
99
- rb_raise(rb_eTypeError, "Expected number type for integral field.");
70
+ rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).",
71
+ name, rb_class2name(CLASS_OF(val)));
100
72
  }
101
73
 
102
74
  // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
@@ -106,13 +78,15 @@ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
106
78
  double dbl_val = NUM2DBL(val);
107
79
  if (floor(dbl_val) != dbl_val) {
108
80
  rb_raise(rb_eRangeError,
109
- "Non-integral floating point value assigned to integer field.");
81
+ "Non-integral floating point value assigned to integer field '%s' (given %s).",
82
+ name, rb_class2name(CLASS_OF(val)));
110
83
  }
111
84
  }
112
85
  if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
113
86
  if (NUM2DBL(val) < 0) {
114
87
  rb_raise(rb_eRangeError,
115
- "Assigning negative value to unsigned integer field.");
88
+ "Assigning negative value to unsigned integer field '%s' (given %s).",
89
+ name, rb_class2name(CLASS_OF(val)));
116
90
  }
117
91
  }
118
92
  }
@@ -137,12 +111,14 @@ VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
137
111
  return value;
138
112
  }
139
113
 
140
- void native_slot_set(upb_fieldtype_t type, VALUE type_class,
114
+ void native_slot_set(const char* name,
115
+ upb_fieldtype_t type, VALUE type_class,
141
116
  void* memory, VALUE value) {
142
- native_slot_set_value_and_case(type, type_class, memory, value, NULL, 0);
117
+ native_slot_set_value_and_case(name, type, type_class, memory, value, NULL, 0);
143
118
  }
144
119
 
145
- void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
120
+ void native_slot_set_value_and_case(const char* name,
121
+ upb_fieldtype_t type, VALUE type_class,
146
122
  void* memory, VALUE value,
147
123
  uint32_t* case_memory,
148
124
  uint32_t case_number) {
@@ -153,13 +129,15 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
153
129
  switch (type) {
154
130
  case UPB_TYPE_FLOAT:
155
131
  if (!is_ruby_num(value)) {
156
- rb_raise(rb_eTypeError, "Expected number type for float field.");
132
+ rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
133
+ name, rb_class2name(CLASS_OF(value)));
157
134
  }
158
135
  DEREF(memory, float) = NUM2DBL(value);
159
136
  break;
160
137
  case UPB_TYPE_DOUBLE:
161
138
  if (!is_ruby_num(value)) {
162
- rb_raise(rb_eTypeError, "Expected number type for double field.");
139
+ rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
140
+ name, rb_class2name(CLASS_OF(value)));
163
141
  }
164
142
  DEREF(memory, double) = NUM2DBL(value);
165
143
  break;
@@ -170,7 +148,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
170
148
  } else if (value == Qfalse) {
171
149
  val = 0;
172
150
  } else {
173
- rb_raise(rb_eTypeError, "Invalid argument for boolean field.");
151
+ rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
152
+ name, rb_class2name(CLASS_OF(value)));
174
153
  }
175
154
  DEREF(memory, int8_t) = val;
176
155
  break;
@@ -179,7 +158,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
179
158
  if (CLASS_OF(value) == rb_cSymbol) {
180
159
  value = rb_funcall(value, rb_intern("to_s"), 0);
181
160
  } else if (CLASS_OF(value) != rb_cString) {
182
- rb_raise(rb_eTypeError, "Invalid argument for string field.");
161
+ rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
162
+ name, rb_class2name(CLASS_OF(value)));
183
163
  }
184
164
 
185
165
  DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -187,7 +167,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
187
167
 
188
168
  case UPB_TYPE_BYTES: {
189
169
  if (CLASS_OF(value) != rb_cString) {
190
- rb_raise(rb_eTypeError, "Invalid argument for string field.");
170
+ rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
171
+ name, rb_class2name(CLASS_OF(value)));
191
172
  }
192
173
 
193
174
  DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -197,9 +178,39 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
197
178
  if (CLASS_OF(value) == CLASS_OF(Qnil)) {
198
179
  value = Qnil;
199
180
  } else if (CLASS_OF(value) != type_class) {
200
- rb_raise(rb_eTypeError,
201
- "Invalid type %s to assign to submessage field.",
202
- rb_class2name(CLASS_OF(value)));
181
+ // check for possible implicit conversions
182
+ VALUE converted_value = NULL;
183
+ char* field_type_name = rb_class2name(type_class);
184
+
185
+ if (strcmp(field_type_name, "Google::Protobuf::Timestamp") == 0 &&
186
+ rb_obj_is_kind_of(value, rb_cTime)) {
187
+ // Time -> Google::Protobuf::Timestamp
188
+ VALUE hash = rb_hash_new();
189
+ rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
190
+ rb_hash_aset(hash, rb_str_new2("nanos"), rb_funcall(value, rb_intern("nsec"), 0));
191
+ VALUE args[1] = { hash };
192
+ converted_value = rb_class_new_instance(1, args, type_class);
193
+ } else if (strcmp(field_type_name, "Google::Protobuf::Duration") == 0 &&
194
+ rb_obj_is_kind_of(value, rb_cNumeric)) {
195
+ // Numeric -> Google::Protobuf::Duration
196
+ VALUE hash = rb_hash_new();
197
+ rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
198
+ VALUE n_value = rb_funcall(value, rb_intern("remainder"), 1, INT2NUM(1));
199
+ n_value = rb_funcall(n_value, rb_intern("*"), 1, INT2NUM(1000000000));
200
+ n_value = rb_funcall(n_value, rb_intern("round"), 0);
201
+ rb_hash_aset(hash, rb_str_new2("nanos"), n_value);
202
+ VALUE args[1] = { hash };
203
+ converted_value = rb_class_new_instance(1, args, type_class);
204
+ }
205
+
206
+ // raise if no suitable conversaion could be found
207
+ if (converted_value == NULL) {
208
+ rb_raise(cTypeError,
209
+ "Invalid type %s to assign to submessage field '%s'.",
210
+ rb_class2name(CLASS_OF(value)), name);
211
+ } else {
212
+ value = converted_value;
213
+ }
203
214
  }
204
215
  DEREF(memory, VALUE) = value;
205
216
  break;
@@ -209,19 +220,19 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
209
220
  if (TYPE(value) == T_STRING) {
210
221
  value = rb_funcall(value, rb_intern("to_sym"), 0);
211
222
  } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
212
- rb_raise(rb_eTypeError,
213
- "Expected number or symbol type for enum field.");
223
+ rb_raise(cTypeError,
224
+ "Expected number or symbol type for enum field '%s'.", name);
214
225
  }
215
226
  if (TYPE(value) == T_SYMBOL) {
216
227
  // Ensure that the given symbol exists in the enum module.
217
228
  VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
218
229
  if (lookup == Qnil) {
219
- rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
230
+ rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
220
231
  } else {
221
232
  int_val = NUM2INT(lookup);
222
233
  }
223
234
  } else {
224
- native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
235
+ native_slot_check_int_range_precision(name, UPB_TYPE_INT32, value);
225
236
  int_val = NUM2INT(value);
226
237
  }
227
238
  DEREF(memory, int32_t) = int_val;
@@ -231,7 +242,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
231
242
  case UPB_TYPE_INT64:
232
243
  case UPB_TYPE_UINT32:
233
244
  case UPB_TYPE_UINT64:
234
- native_slot_check_int_range_precision(type, value);
245
+ native_slot_check_int_range_precision(name, type, value);
235
246
  switch (type) {
236
247
  case UPB_TYPE_INT32:
237
248
  DEREF(memory, int32_t) = NUM2INT(value);
@@ -404,7 +415,12 @@ const upb_msgdef *map_entry_msgdef(const upb_fielddef* field) {
404
415
  }
405
416
 
406
417
  bool is_map_field(const upb_fielddef *field) {
407
- return tryget_map_entry_msgdef(field) != NULL;
418
+ const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
419
+ if (subdef == NULL) return false;
420
+
421
+ // Map fields are a proto3 feature.
422
+ // If we're using proto2 syntax we need to fallback to the repeated field.
423
+ return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
408
424
  }
409
425
 
410
426
  const upb_fielddef* map_field_key(const upb_fielddef* field) {
@@ -433,6 +449,12 @@ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
433
449
  // Memory layout management.
434
450
  // -----------------------------------------------------------------------------
435
451
 
452
+ bool field_contains_hasbit(MessageLayout* layout,
453
+ const upb_fielddef* field) {
454
+ return layout->fields[upb_fielddef_index(field)].hasbit !=
455
+ MESSAGE_FIELD_NO_HASBIT;
456
+ }
457
+
436
458
  static size_t align_up_to(size_t offset, size_t granularity) {
437
459
  // Granularity must be a power of two.
438
460
  return (offset + granularity - 1) & ~(granularity - 1);
@@ -447,6 +469,23 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
447
469
 
448
470
  layout->fields = ALLOC_N(MessageField, nfields);
449
471
 
472
+ size_t hasbit = 0;
473
+ for (upb_msg_field_begin(&it, msgdef);
474
+ !upb_msg_field_done(&it);
475
+ upb_msg_field_next(&it)) {
476
+ const upb_fielddef* field = upb_msg_iter_field(&it);
477
+ if (upb_fielddef_haspresence(field)) {
478
+ layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
479
+ } else {
480
+ layout->fields[upb_fielddef_index(field)].hasbit =
481
+ MESSAGE_FIELD_NO_HASBIT;
482
+ }
483
+ }
484
+
485
+ if (hasbit != 0) {
486
+ off += (hasbit + 8 - 1) / 8;
487
+ }
488
+
450
489
  for (upb_msg_field_begin(&it, msgdef);
451
490
  !upb_msg_field_done(&it);
452
491
  upb_msg_field_next(&it)) {
@@ -569,6 +608,137 @@ static uint32_t* slot_oneof_case(MessageLayout* layout,
569
608
  layout->fields[upb_fielddef_index(field)].case_offset);
570
609
  }
571
610
 
611
+ static void slot_set_hasbit(MessageLayout* layout,
612
+ const void* storage,
613
+ const upb_fielddef* field) {
614
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
615
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
616
+
617
+ ((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
618
+ }
619
+
620
+ static void slot_clear_hasbit(MessageLayout* layout,
621
+ const void* storage,
622
+ const upb_fielddef* field) {
623
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
624
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
625
+ ((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
626
+ }
627
+
628
+ static bool slot_is_hasbit_set(MessageLayout* layout,
629
+ const void* storage,
630
+ const upb_fielddef* field) {
631
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
632
+ if (hasbit == MESSAGE_FIELD_NO_HASBIT) {
633
+ return false;
634
+ }
635
+
636
+ return DEREF_OFFSET(
637
+ (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
638
+ }
639
+
640
+ VALUE layout_has(MessageLayout* layout,
641
+ const void* storage,
642
+ const upb_fielddef* field) {
643
+ assert(field_contains_hasbit(layout, field));
644
+ return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
645
+ }
646
+
647
+ void layout_clear(MessageLayout* layout,
648
+ const void* storage,
649
+ const upb_fielddef* field) {
650
+ void* memory = slot_memory(layout, storage, field);
651
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
652
+
653
+ if (field_contains_hasbit(layout, field)) {
654
+ slot_clear_hasbit(layout, storage, field);
655
+ }
656
+
657
+ if (upb_fielddef_containingoneof(field)) {
658
+ memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
659
+ *oneof_case = ONEOF_CASE_NONE;
660
+ } else if (is_map_field(field)) {
661
+ VALUE map = Qnil;
662
+
663
+ const upb_fielddef* key_field = map_field_key(field);
664
+ const upb_fielddef* value_field = map_field_value(field);
665
+ VALUE type_class = field_type_class(value_field);
666
+
667
+ if (type_class != Qnil) {
668
+ VALUE args[3] = {
669
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
670
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
671
+ type_class,
672
+ };
673
+ map = rb_class_new_instance(3, args, cMap);
674
+ } else {
675
+ VALUE args[2] = {
676
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
677
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
678
+ };
679
+ map = rb_class_new_instance(2, args, cMap);
680
+ }
681
+
682
+ DEREF(memory, VALUE) = map;
683
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
684
+ VALUE ary = Qnil;
685
+
686
+ VALUE type_class = field_type_class(field);
687
+
688
+ if (type_class != Qnil) {
689
+ VALUE args[2] = {
690
+ fieldtype_to_ruby(upb_fielddef_type(field)),
691
+ type_class,
692
+ };
693
+ ary = rb_class_new_instance(2, args, cRepeatedField);
694
+ } else {
695
+ VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
696
+ ary = rb_class_new_instance(1, args, cRepeatedField);
697
+ }
698
+
699
+ DEREF(memory, VALUE) = ary;
700
+ } else {
701
+ native_slot_set(upb_fielddef_name(field),
702
+ upb_fielddef_type(field), field_type_class(field),
703
+ memory, layout_get_default(field));
704
+ }
705
+ }
706
+
707
+ VALUE layout_get_default(const upb_fielddef *field) {
708
+ switch (upb_fielddef_type(field)) {
709
+ case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
710
+ case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
711
+ case UPB_TYPE_BOOL:
712
+ return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
713
+ case UPB_TYPE_MESSAGE: return Qnil;
714
+ case UPB_TYPE_ENUM: {
715
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
716
+ int32_t num = upb_fielddef_defaultint32(field);
717
+ const char *label = upb_enumdef_iton(enumdef, num);
718
+ if (label) {
719
+ return ID2SYM(rb_intern(label));
720
+ } else {
721
+ return INT2NUM(num);
722
+ }
723
+ }
724
+ case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
725
+ case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
726
+ case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
727
+ case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
728
+ case UPB_TYPE_STRING:
729
+ case UPB_TYPE_BYTES: {
730
+ size_t size;
731
+ const char *str = upb_fielddef_defaultstr(field, &size);
732
+ VALUE str_rb = rb_str_new(str, size);
733
+
734
+ rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
735
+ kRubyString8bitEncoding : kRubyStringUtf8Encoding);
736
+ rb_obj_freeze(str_rb);
737
+ return str_rb;
738
+ }
739
+ default: return Qnil;
740
+ }
741
+ }
572
742
 
573
743
  VALUE layout_get(MessageLayout* layout,
574
744
  const void* storage,
@@ -576,15 +746,24 @@ VALUE layout_get(MessageLayout* layout,
576
746
  void* memory = slot_memory(layout, storage, field);
577
747
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
578
748
 
749
+ bool field_set;
750
+ if (field_contains_hasbit(layout, field)) {
751
+ field_set = slot_is_hasbit_set(layout, storage, field);
752
+ } else {
753
+ field_set = true;
754
+ }
755
+
579
756
  if (upb_fielddef_containingoneof(field)) {
580
757
  if (*oneof_case != upb_fielddef_number(field)) {
581
- return value_from_default(field);
758
+ return layout_get_default(field);
582
759
  }
583
760
  return native_slot_get(upb_fielddef_type(field),
584
761
  field_type_class(field),
585
762
  memory);
586
763
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
587
764
  return *((VALUE *)memory);
765
+ } else if (!field_set) {
766
+ return layout_get_default(field);
588
767
  } else {
589
768
  return native_slot_get(upb_fielddef_type(field),
590
769
  field_type_class(field),
@@ -598,18 +777,18 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
598
777
 
599
778
  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
600
779
  RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
601
- rb_raise(rb_eTypeError, "Expected repeated field array");
780
+ rb_raise(cTypeError, "Expected repeated field array");
602
781
  }
603
782
 
604
783
  self = ruby_to_RepeatedField(val);
605
784
  if (self->field_type != upb_fielddef_type(field)) {
606
- rb_raise(rb_eTypeError, "Repeated field array has wrong element type");
785
+ rb_raise(cTypeError, "Repeated field array has wrong element type");
607
786
  }
608
787
 
609
- if (self->field_type == UPB_TYPE_MESSAGE) {
788
+ if (self->field_type == UPB_TYPE_MESSAGE) {
610
789
  if (self->field_type_class !=
611
790
  Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
612
- rb_raise(rb_eTypeError,
791
+ rb_raise(cTypeError,
613
792
  "Repeated field array has wrong message class");
614
793
  }
615
794
  }
@@ -618,7 +797,7 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
618
797
  if (self->field_type == UPB_TYPE_ENUM) {
619
798
  if (self->field_type_class !=
620
799
  EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
621
- rb_raise(rb_eTypeError,
800
+ rb_raise(cTypeError,
622
801
  "Repeated field array has wrong enum class");
623
802
  }
624
803
  }
@@ -631,21 +810,21 @@ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
631
810
 
632
811
  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
633
812
  RTYPEDDATA_TYPE(val) != &Map_type) {
634
- rb_raise(rb_eTypeError, "Expected Map instance");
813
+ rb_raise(cTypeError, "Expected Map instance");
635
814
  }
636
815
 
637
816
  self = ruby_to_Map(val);
638
817
  if (self->key_type != upb_fielddef_type(key_field)) {
639
- rb_raise(rb_eTypeError, "Map key type does not match field's key type");
818
+ rb_raise(cTypeError, "Map key type does not match field's key type");
640
819
  }
641
820
  if (self->value_type != upb_fielddef_type(value_field)) {
642
- rb_raise(rb_eTypeError, "Map value type does not match field's value type");
821
+ rb_raise(cTypeError, "Map value type does not match field's value type");
643
822
  }
644
823
  if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
645
824
  upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
646
825
  if (self->value_type_class !=
647
826
  get_def_obj(upb_fielddef_subdef(value_field))) {
648
- rb_raise(rb_eTypeError,
827
+ rb_raise(cTypeError,
649
828
  "Map value type has wrong message/enum class");
650
829
  }
651
830
  }
@@ -678,6 +857,7 @@ void layout_set(MessageLayout* layout,
678
857
  // use native_slot_set_value_and_case(), which ensures that both the value
679
858
  // and case number are altered atomically (w.r.t. the Ruby VM).
680
859
  native_slot_set_value_and_case(
860
+ upb_fielddef_name(field),
681
861
  upb_fielddef_type(field), field_type_class(field),
682
862
  memory, val,
683
863
  oneof_case, upb_fielddef_number(field));
@@ -689,67 +869,25 @@ void layout_set(MessageLayout* layout,
689
869
  check_repeated_field_type(val, field);
690
870
  DEREF(memory, VALUE) = val;
691
871
  } else {
692
- native_slot_set(upb_fielddef_type(field), field_type_class(field),
872
+ native_slot_set(upb_fielddef_name(field),
873
+ upb_fielddef_type(field), field_type_class(field),
693
874
  memory, val);
694
875
  }
876
+
877
+ if (layout->fields[upb_fielddef_index(field)].hasbit !=
878
+ MESSAGE_FIELD_NO_HASBIT) {
879
+ slot_set_hasbit(layout, storage, field);
880
+ }
695
881
  }
696
882
 
697
883
  void layout_init(MessageLayout* layout,
698
884
  void* storage) {
885
+
699
886
  upb_msg_field_iter it;
700
887
  for (upb_msg_field_begin(&it, layout->msgdef);
701
888
  !upb_msg_field_done(&it);
702
889
  upb_msg_field_next(&it)) {
703
- const upb_fielddef* field = upb_msg_iter_field(&it);
704
- void* memory = slot_memory(layout, storage, field);
705
- uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
706
-
707
- if (upb_fielddef_containingoneof(field)) {
708
- memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
709
- *oneof_case = ONEOF_CASE_NONE;
710
- } else if (is_map_field(field)) {
711
- VALUE map = Qnil;
712
-
713
- const upb_fielddef* key_field = map_field_key(field);
714
- const upb_fielddef* value_field = map_field_value(field);
715
- VALUE type_class = field_type_class(value_field);
716
-
717
- if (type_class != Qnil) {
718
- VALUE args[3] = {
719
- fieldtype_to_ruby(upb_fielddef_type(key_field)),
720
- fieldtype_to_ruby(upb_fielddef_type(value_field)),
721
- type_class,
722
- };
723
- map = rb_class_new_instance(3, args, cMap);
724
- } else {
725
- VALUE args[2] = {
726
- fieldtype_to_ruby(upb_fielddef_type(key_field)),
727
- fieldtype_to_ruby(upb_fielddef_type(value_field)),
728
- };
729
- map = rb_class_new_instance(2, args, cMap);
730
- }
731
-
732
- DEREF(memory, VALUE) = map;
733
- } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
734
- VALUE ary = Qnil;
735
-
736
- VALUE type_class = field_type_class(field);
737
-
738
- if (type_class != Qnil) {
739
- VALUE args[2] = {
740
- fieldtype_to_ruby(upb_fielddef_type(field)),
741
- type_class,
742
- };
743
- ary = rb_class_new_instance(2, args, cRepeatedField);
744
- } else {
745
- VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
746
- ary = rb_class_new_instance(1, args, cRepeatedField);
747
- }
748
-
749
- DEREF(memory, VALUE) = ary;
750
- } else {
751
- native_slot_init(upb_fielddef_type(field), memory);
752
- }
890
+ layout_clear(layout, storage, upb_msg_iter_field(&it));
753
891
  }
754
892
  }
755
893
 
@@ -796,6 +934,11 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
796
934
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
797
935
  DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
798
936
  } else {
937
+ if (field_contains_hasbit(layout, field)) {
938
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
939
+ slot_set_hasbit(layout, to, field);
940
+ }
941
+
799
942
  native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
800
943
  }
801
944
  }
@@ -825,6 +968,11 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
825
968
  DEREF(to_memory, VALUE) =
826
969
  RepeatedField_deep_copy(DEREF(from_memory, VALUE));
827
970
  } else {
971
+ if (field_contains_hasbit(layout, field)) {
972
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
973
+ slot_set_hasbit(layout, to, field);
974
+ }
975
+
828
976
  native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
829
977
  }
830
978
  }
@@ -861,8 +1009,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
861
1009
  return Qfalse;
862
1010
  }
863
1011
  } else {
864
- if (!native_slot_eq(upb_fielddef_type(field),
865
- msg1_memory, msg2_memory)) {
1012
+ if (slot_is_hasbit_set(layout, msg1, field) !=
1013
+ slot_is_hasbit_set(layout, msg2, field) ||
1014
+ !native_slot_eq(upb_fielddef_type(field),
1015
+ msg1_memory, msg2_memory)) {
866
1016
  return Qfalse;
867
1017
  }
868
1018
  }