google-protobuf 3.6.1 → 3.9.1

Sign up to get free protection for your applications and to get access to all the features.

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
  }