|
@@ -178,6 +178,45 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
|
|
|
+ MessageHeader* self;
|
|
|
+ VALUE method_name, method_str;
|
|
|
+ char* name;
|
|
|
+ size_t name_len;
|
|
|
+ bool setter;
|
|
|
+ const upb_oneofdef* o;
|
|
|
+ const upb_fielddef* f;
|
|
|
+
|
|
|
+ TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
|
|
+ if (argc < 1) {
|
|
|
+ rb_raise(rb_eArgError, "Expected method name as first argument.");
|
|
|
+ }
|
|
|
+ method_name = argv[0];
|
|
|
+ if (!SYMBOL_P(method_name)) {
|
|
|
+ rb_raise(rb_eArgError, "Expected symbol as method name.");
|
|
|
+ }
|
|
|
+ method_str = rb_id2str(SYM2ID(method_name));
|
|
|
+ name = RSTRING_PTR(method_str);
|
|
|
+ name_len = RSTRING_LEN(method_str);
|
|
|
+ setter = false;
|
|
|
+
|
|
|
+ // Setters have names that end in '='.
|
|
|
+ if (name[name_len - 1] == '=') {
|
|
|
+ setter = true;
|
|
|
+ name_len--;
|
|
|
+ }
|
|
|
+
|
|
|
+ // See if this name corresponds to either a oneof or field in this message.
|
|
|
+ if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
|
|
|
+ &o)) {
|
|
|
+ return rb_call_super(argc, argv);
|
|
|
+ }
|
|
|
+ if (o != NULL) {
|
|
|
+ return setter ? Qfalse : Qtrue;
|
|
|
+ }
|
|
|
+ return Qtrue;
|
|
|
+}
|
|
|
+
|
|
|
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
|
MessageHeader* self;
|
|
|
VALUE method_str;
|
|
@@ -303,6 +342,9 @@ VALUE Message_deep_copy(VALUE _self) {
|
|
|
* field is of a primitive type).
|
|
|
*/
|
|
|
VALUE Message_eq(VALUE _self, VALUE _other) {
|
|
|
+ if (TYPE(_self) != TYPE(_other)) {
|
|
|
+ return Qfalse;
|
|
|
+ }
|
|
|
MessageHeader* self;
|
|
|
MessageHeader* other;
|
|
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
|
@@ -459,6 +501,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
|
|
|
|
|
rb_define_method(klass, "method_missing",
|
|
|
Message_method_missing, -1);
|
|
|
+ rb_define_method(klass, "respond_to_missing?",
|
|
|
+ Message_respond_to_missing, -1);
|
|
|
rb_define_method(klass, "initialize", Message_initialize, -1);
|
|
|
rb_define_method(klass, "dup", Message_dup, 0);
|
|
|
// Also define #clone so that we don't inherit Object#clone.
|