google-protobuf 3.6.0 → 3.7.0
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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +554 -71
- data/ext/google/protobuf_c/encode_decode.c +245 -66
- data/ext/google/protobuf_c/extconf.rb +5 -1
- data/ext/google/protobuf_c/message.c +135 -69
- data/ext/google/protobuf_c/protobuf.c +4 -0
- data/ext/google/protobuf_c/protobuf.h +62 -2
- data/ext/google/protobuf_c/storage.c +213 -106
- data/ext/google/protobuf_c/upb.c +4126 -1721
- data/ext/google/protobuf_c/upb.h +1125 -339
- data/ext/google/protobuf_c/wrap_memcpy.c +1 -1
- data/lib/google/protobuf/any_pb.rb +5 -3
- data/lib/google/protobuf/api_pb.rb +23 -21
- data/lib/google/protobuf/duration_pb.rb +5 -3
- data/lib/google/protobuf/empty_pb.rb +3 -1
- data/lib/google/protobuf/field_mask_pb.rb +4 -2
- data/lib/google/protobuf/repeated_field.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +4 -2
- data/lib/google/protobuf/struct_pb.rb +19 -17
- data/lib/google/protobuf/timestamp_pb.rb +5 -3
- data/lib/google/protobuf/type_pb.rb +68 -66
- data/lib/google/protobuf/well_known_types.rb +12 -0
- data/lib/google/protobuf/wrappers_pb.rb +28 -26
- data/lib/google/protobuf.rb +3 -2
- data/tests/basic.rb +137 -1179
- data/tests/generated_code_test.rb +5 -3
- metadata +3 -3
| @@ -79,7 +79,7 @@ VALUE Message_alloc(VALUE klass) { | |
| 79 79 | 
             
              return ret;
         | 
| 80 80 | 
             
            }
         | 
| 81 81 |  | 
| 82 | 
            -
            static  | 
| 82 | 
            +
            static const upb_fielddef* which_oneof_field(MessageHeader* self, const upb_oneofdef* o) {
         | 
| 83 83 | 
             
              upb_oneof_iter it;
         | 
| 84 84 | 
             
              size_t case_ofs;
         | 
| 85 85 | 
             
              uint32_t oneof_case;
         | 
| @@ -88,7 +88,7 @@ static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) { | |
| 88 88 |  | 
| 89 89 | 
             
              // If no fields in the oneof, always nil.
         | 
| 90 90 | 
             
              if (upb_oneofdef_numfields(o) == 0) {
         | 
| 91 | 
            -
                return  | 
| 91 | 
            +
                return NULL;
         | 
| 92 92 | 
             
              }
         | 
| 93 93 | 
             
              // Grab the first field in the oneof so we can get its layout info to find the
         | 
| 94 94 | 
             
              // oneof_case field.
         | 
| @@ -103,22 +103,83 @@ static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) { | |
| 103 103 | 
             
              oneof_case = *((uint32_t*)((char*)Message_data(self) + case_ofs));
         | 
| 104 104 |  | 
| 105 105 | 
             
              if (oneof_case == ONEOF_CASE_NONE) {
         | 
| 106 | 
            -
                return  | 
| 106 | 
            +
                return NULL;
         | 
| 107 107 | 
             
              }
         | 
| 108 108 |  | 
| 109 109 | 
             
              // oneof_case is a field index, so find that field.
         | 
| 110 110 | 
             
              f = upb_oneofdef_itof(o, oneof_case);
         | 
| 111 111 | 
             
              assert(f != NULL);
         | 
| 112 112 |  | 
| 113 | 
            -
              return  | 
| 113 | 
            +
              return f;
         | 
| 114 | 
            +
            }
         | 
| 115 | 
            +
             | 
| 116 | 
            +
            enum {
         | 
| 117 | 
            +
              METHOD_UNKNOWN = 0,
         | 
| 118 | 
            +
              METHOD_GETTER = 1,
         | 
| 119 | 
            +
              METHOD_SETTER = 2,
         | 
| 120 | 
            +
              METHOD_CLEAR = 3,
         | 
| 121 | 
            +
              METHOD_PRESENCE = 4
         | 
| 122 | 
            +
            };
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            static int extract_method_call(VALUE method_name, MessageHeader* self,
         | 
| 125 | 
            +
            			       const upb_fielddef **f, const upb_oneofdef **o) {
         | 
| 126 | 
            +
              Check_Type(method_name, T_SYMBOL);
         | 
| 127 | 
            +
             | 
| 128 | 
            +
              VALUE method_str = rb_id2str(SYM2ID(method_name));
         | 
| 129 | 
            +
              char* name = RSTRING_PTR(method_str);
         | 
| 130 | 
            +
              size_t name_len = RSTRING_LEN(method_str);
         | 
| 131 | 
            +
              int accessor_type;
         | 
| 132 | 
            +
              const upb_oneofdef* test_o;
         | 
| 133 | 
            +
              const upb_fielddef* test_f;
         | 
| 134 | 
            +
             | 
| 135 | 
            +
              if (name[name_len - 1] == '=') {
         | 
| 136 | 
            +
                accessor_type = METHOD_SETTER;
         | 
| 137 | 
            +
                name_len--;
         | 
| 138 | 
            +
                // We want to ensure if the proto has something named clear_foo or has_foo?,
         | 
| 139 | 
            +
                // we don't strip the prefix.
         | 
| 140 | 
            +
              } else if (strncmp("clear_", name, 6) == 0 &&
         | 
| 141 | 
            +
                         !upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
         | 
| 142 | 
            +
            				    &test_f, &test_o)) {
         | 
| 143 | 
            +
                accessor_type = METHOD_CLEAR;
         | 
| 144 | 
            +
                name = name + 6;
         | 
| 145 | 
            +
                name_len = name_len - 6;
         | 
| 146 | 
            +
              } else if (strncmp("has_", name, 4) == 0 && name[name_len - 1] == '?' &&
         | 
| 147 | 
            +
                         !upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
         | 
| 148 | 
            +
            				    &test_f, &test_o)) {
         | 
| 149 | 
            +
                accessor_type = METHOD_PRESENCE;
         | 
| 150 | 
            +
                name = name + 4;
         | 
| 151 | 
            +
                name_len = name_len - 5;
         | 
| 152 | 
            +
              } else {
         | 
| 153 | 
            +
                accessor_type = METHOD_GETTER;
         | 
| 154 | 
            +
              }
         | 
| 155 | 
            +
             | 
| 156 | 
            +
              // Verify the name corresponds to a oneof or field in this message.
         | 
| 157 | 
            +
              if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len,
         | 
| 158 | 
            +
            			     &test_f, &test_o)) {
         | 
| 159 | 
            +
                return METHOD_UNKNOWN;
         | 
| 160 | 
            +
              }
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              // Method calls like 'has_foo?' are not allowed if field "foo" does not have
         | 
| 163 | 
            +
              // a hasbit (e.g. repeated fields or non-message type fields for proto3
         | 
| 164 | 
            +
              // syntax).
         | 
| 165 | 
            +
              if (accessor_type == METHOD_PRESENCE && test_f != NULL &&
         | 
| 166 | 
            +
                  !upb_fielddef_haspresence(test_f)) {
         | 
| 167 | 
            +
                return METHOD_UNKNOWN;
         | 
| 168 | 
            +
              }
         | 
| 169 | 
            +
             | 
| 170 | 
            +
              *o = test_o;
         | 
| 171 | 
            +
              *f = test_f;
         | 
| 172 | 
            +
              return accessor_type;
         | 
| 114 173 | 
             
            }
         | 
| 115 174 |  | 
| 116 175 | 
             
            /*
         | 
| 117 176 | 
             
             * call-seq:
         | 
| 118 177 | 
             
             *     Message.method_missing(*args)
         | 
| 119 178 | 
             
             *
         | 
| 120 | 
            -
             * Provides accessors and setters  | 
| 121 | 
            -
             *  | 
| 179 | 
            +
             * Provides accessors and setters and methods to clear and check for presence of
         | 
| 180 | 
            +
             * message fields according to their field names.
         | 
| 181 | 
            +
             *
         | 
| 182 | 
            +
             * For any field whose name does not conflict with a built-in method, an
         | 
| 122 183 | 
             
             * accessor is provided with the same name as the field, and a setter is
         | 
| 123 184 | 
             
             * provided with the name of the field plus the '=' suffix. Thus, given a
         | 
| 124 185 | 
             
             * message instance 'msg' with field 'foo', the following code is valid:
         | 
| @@ -129,13 +190,17 @@ static VALUE which_oneof_field(MessageHeader* self, const upb_oneofdef* o) { | |
| 129 190 | 
             
             * This method also provides read-only accessors for oneofs. If a oneof exists
         | 
| 130 191 | 
             
             * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to
         | 
| 131 192 | 
             
             * the name of the field in that oneof that is currently set, or nil if none.
         | 
| 193 | 
            +
             *
         | 
| 194 | 
            +
             * It also provides methods of the form 'clear_fieldname' to clear the value
         | 
| 195 | 
            +
             * of the field 'fieldname'. For basic data types, this will set the default
         | 
| 196 | 
            +
             * value of the field.
         | 
| 197 | 
            +
             *
         | 
| 198 | 
            +
             * Additionally, it provides methods of the form 'has_fieldname?', which returns
         | 
| 199 | 
            +
             * true if the field 'fieldname' is set in the message object, else false. For
         | 
| 200 | 
            +
             * 'proto3' syntax, calling this for a basic type field will result in an error.
         | 
| 132 201 | 
             
             */
         | 
| 133 202 | 
             
            VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
         | 
| 134 203 | 
             
              MessageHeader* self;
         | 
| 135 | 
            -
              VALUE method_name, method_str;
         | 
| 136 | 
            -
              char* name;
         | 
| 137 | 
            -
              size_t name_len;
         | 
| 138 | 
            -
              bool setter;
         | 
| 139 204 | 
             
              const upb_oneofdef* o;
         | 
| 140 205 | 
             
              const upb_fielddef* f;
         | 
| 141 206 |  | 
| @@ -143,54 +208,54 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { | |
| 143 208 | 
             
              if (argc < 1) {
         | 
| 144 209 | 
             
                rb_raise(rb_eArgError, "Expected method name as first argument.");
         | 
| 145 210 | 
             
              }
         | 
| 146 | 
            -
              method_name = argv[0];
         | 
| 147 | 
            -
              if (!SYMBOL_P(method_name)) {
         | 
| 148 | 
            -
                rb_raise(rb_eArgError, "Expected symbol as method name.");
         | 
| 149 | 
            -
              }
         | 
| 150 | 
            -
              method_str = rb_id2str(SYM2ID(method_name));
         | 
| 151 | 
            -
              name = RSTRING_PTR(method_str);
         | 
| 152 | 
            -
              name_len = RSTRING_LEN(method_str);
         | 
| 153 | 
            -
              setter = false;
         | 
| 154 211 |  | 
| 155 | 
            -
               | 
| 156 | 
            -
              if ( | 
| 157 | 
            -
                setter = true;
         | 
| 158 | 
            -
                name_len--;
         | 
| 159 | 
            -
              }
         | 
| 160 | 
            -
             | 
| 161 | 
            -
              // See if this name corresponds to either a oneof or field in this message.
         | 
| 162 | 
            -
              if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
         | 
| 163 | 
            -
                                         &o)) {
         | 
| 212 | 
            +
              int accessor_type = extract_method_call(argv[0], self, &f, &o);
         | 
| 213 | 
            +
              if (accessor_type == METHOD_UNKNOWN || (o == NULL && f == NULL) ) {
         | 
| 164 214 | 
             
                return rb_call_super(argc, argv);
         | 
| 215 | 
            +
              } else if (accessor_type == METHOD_SETTER) {
         | 
| 216 | 
            +
                if (argc != 2) {
         | 
| 217 | 
            +
                  rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc);
         | 
| 218 | 
            +
                }
         | 
| 219 | 
            +
              } else if (argc != 1) {
         | 
| 220 | 
            +
                rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc);
         | 
| 165 221 | 
             
              }
         | 
| 166 222 |  | 
| 223 | 
            +
              // Return which of the oneof fields are set
         | 
| 167 224 | 
             
              if (o != NULL) {
         | 
| 168 | 
            -
                 | 
| 169 | 
            -
                if (setter) {
         | 
| 225 | 
            +
                if (accessor_type == METHOD_SETTER) {
         | 
| 170 226 | 
             
                  rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
         | 
| 171 227 | 
             
                }
         | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
                 | 
| 175 | 
            -
             | 
| 176 | 
            -
                if ( | 
| 177 | 
            -
                  if ( | 
| 178 | 
            -
             | 
| 228 | 
            +
             | 
| 229 | 
            +
                const upb_fielddef* oneof_field = which_oneof_field(self, o);
         | 
| 230 | 
            +
                if (accessor_type == METHOD_PRESENCE) {
         | 
| 231 | 
            +
                  return oneof_field == NULL ? Qfalse : Qtrue;
         | 
| 232 | 
            +
                } else if (accessor_type == METHOD_CLEAR) {
         | 
| 233 | 
            +
                  if (oneof_field != NULL) {
         | 
| 234 | 
            +
            	layout_clear(self->descriptor->layout, Message_data(self), oneof_field);
         | 
| 179 235 | 
             
                  }
         | 
| 180 | 
            -
                  layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
         | 
| 181 236 | 
             
                  return Qnil;
         | 
| 182 237 | 
             
                } else {
         | 
| 183 | 
            -
                   | 
| 238 | 
            +
                  // METHOD_ACCESSOR
         | 
| 239 | 
            +
                  return oneof_field == NULL ? Qnil :
         | 
| 240 | 
            +
            	ID2SYM(rb_intern(upb_fielddef_name(oneof_field)));
         | 
| 184 241 | 
             
                }
         | 
| 242 | 
            +
              // Otherwise we're operating on a single proto field
         | 
| 243 | 
            +
              } else if (accessor_type == METHOD_SETTER) {
         | 
| 244 | 
            +
                layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
         | 
| 245 | 
            +
                return Qnil;
         | 
| 246 | 
            +
              } else if (accessor_type == METHOD_CLEAR) {
         | 
| 247 | 
            +
                layout_clear(self->descriptor->layout, Message_data(self), f);
         | 
| 248 | 
            +
                return Qnil;
         | 
| 249 | 
            +
              } else if (accessor_type == METHOD_PRESENCE) {
         | 
| 250 | 
            +
                return layout_has(self->descriptor->layout, Message_data(self), f);
         | 
| 251 | 
            +
              } else {
         | 
| 252 | 
            +
                return layout_get(self->descriptor->layout, Message_data(self), f);
         | 
| 185 253 | 
             
              }
         | 
| 186 254 | 
             
            }
         | 
| 187 255 |  | 
| 256 | 
            +
             | 
| 188 257 | 
             
            VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
         | 
| 189 258 | 
             
              MessageHeader* self;
         | 
| 190 | 
            -
              VALUE method_name, method_str;
         | 
| 191 | 
            -
              char* name;
         | 
| 192 | 
            -
              size_t name_len;
         | 
| 193 | 
            -
              bool setter;
         | 
| 194 259 | 
             
              const upb_oneofdef* o;
         | 
| 195 260 | 
             
              const upb_fielddef* f;
         | 
| 196 261 |  | 
| @@ -198,30 +263,15 @@ VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { | |
| 198 263 | 
             
              if (argc < 1) {
         | 
| 199 264 | 
             
                rb_raise(rb_eArgError, "Expected method name as first argument.");
         | 
| 200 265 | 
             
              }
         | 
| 201 | 
            -
              method_name = argv[0];
         | 
| 202 | 
            -
              if (!SYMBOL_P(method_name)) {
         | 
| 203 | 
            -
                rb_raise(rb_eArgError, "Expected symbol as method name.");
         | 
| 204 | 
            -
              }
         | 
| 205 | 
            -
              method_str = rb_id2str(SYM2ID(method_name));
         | 
| 206 | 
            -
              name = RSTRING_PTR(method_str);
         | 
| 207 | 
            -
              name_len = RSTRING_LEN(method_str);
         | 
| 208 | 
            -
              setter = false;
         | 
| 209 266 |  | 
| 210 | 
            -
               | 
| 211 | 
            -
              if ( | 
| 212 | 
            -
                setter = true;
         | 
| 213 | 
            -
                name_len--;
         | 
| 214 | 
            -
              }
         | 
| 215 | 
            -
             | 
| 216 | 
            -
              // See if this name corresponds to either a oneof or field in this message.
         | 
| 217 | 
            -
              if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
         | 
| 218 | 
            -
                                         &o)) {
         | 
| 267 | 
            +
              int accessor_type = extract_method_call(argv[0], self, &f, &o);
         | 
| 268 | 
            +
              if (accessor_type == METHOD_UNKNOWN) {
         | 
| 219 269 | 
             
                return rb_call_super(argc, argv);
         | 
| 270 | 
            +
              } else if (o != NULL) {
         | 
| 271 | 
            +
                return accessor_type == METHOD_SETTER ? Qfalse : Qtrue;
         | 
| 272 | 
            +
              } else {
         | 
| 273 | 
            +
                return Qtrue;
         | 
| 220 274 | 
             
              }
         | 
| 221 | 
            -
              if (o != NULL) {
         | 
| 222 | 
            -
                return setter ? Qfalse : Qtrue;
         | 
| 223 | 
            -
              }
         | 
| 224 | 
            -
              return Qtrue;
         | 
| 225 275 | 
             
            }
         | 
| 226 276 |  | 
| 227 277 | 
             
            VALUE create_submsg_from_hash(const upb_fielddef *f, VALUE hash) {
         | 
| @@ -256,6 +306,10 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { | |
| 256 306 | 
             
                         "Unknown field name '%s' in initialization map entry.", name);
         | 
| 257 307 | 
             
              }
         | 
| 258 308 |  | 
| 309 | 
            +
              if (TYPE(val) == T_NIL) {
         | 
| 310 | 
            +
                return 0;
         | 
| 311 | 
            +
              }
         | 
| 312 | 
            +
             | 
| 259 313 | 
             
              if (is_map_field(f)) {
         | 
| 260 314 | 
             
                VALUE map;
         | 
| 261 315 |  | 
| @@ -440,13 +494,25 @@ VALUE Message_to_h(VALUE _self) { | |
| 440 494 | 
             
                   !upb_msg_field_done(&it);
         | 
| 441 495 | 
             
                   upb_msg_field_next(&it)) {
         | 
| 442 496 | 
             
                const upb_fielddef* field = upb_msg_iter_field(&it);
         | 
| 497 | 
            +
             | 
| 498 | 
            +
                // For proto2, do not include fields which are not set.
         | 
| 499 | 
            +
                if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
         | 
| 500 | 
            +
            	field_contains_hasbit(self->descriptor->layout, field) &&
         | 
| 501 | 
            +
            	!layout_has(self->descriptor->layout, Message_data(self), field)) {
         | 
| 502 | 
            +
                  continue;
         | 
| 503 | 
            +
                }
         | 
| 504 | 
            +
             | 
| 443 505 | 
             
                VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
         | 
| 444 506 | 
             
                                             field);
         | 
| 445 507 | 
             
                VALUE msg_key   = ID2SYM(rb_intern(upb_fielddef_name(field)));
         | 
| 446 | 
            -
                if ( | 
| 508 | 
            +
                if (is_map_field(field)) {
         | 
| 447 509 | 
             
                  msg_value = Map_to_h(msg_value);
         | 
| 448 510 | 
             
                } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
         | 
| 449 511 | 
             
                  msg_value = RepeatedField_to_ary(msg_value);
         | 
| 512 | 
            +
                  if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
         | 
| 513 | 
            +
                      RARRAY_LEN(msg_value) == 0) {
         | 
| 514 | 
            +
                    continue;
         | 
| 515 | 
            +
                  }
         | 
| 450 516 |  | 
| 451 517 | 
             
                  if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
         | 
| 452 518 | 
             
                    for (int i = 0; i < RARRAY_LEN(msg_value); i++) {
         | 
| @@ -454,6 +520,7 @@ VALUE Message_to_h(VALUE _self) { | |
| 454 520 | 
             
                      rb_ary_store(msg_value, i, Message_to_h(elem));
         | 
| 455 521 | 
             
                    }
         | 
| 456 522 | 
             
                  }
         | 
| 523 | 
            +
             | 
| 457 524 | 
             
                } else if (msg_value != Qnil &&
         | 
| 458 525 | 
             
                           upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
         | 
| 459 526 | 
             
                  msg_value = Message_to_h(msg_value);
         | 
| @@ -561,7 +628,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) { | |
| 561 628 | 
             
              rb_define_method(klass, "[]=", Message_index_set, 2);
         | 
| 562 629 | 
             
              rb_define_singleton_method(klass, "decode", Message_decode, 1);
         | 
| 563 630 | 
             
              rb_define_singleton_method(klass, "encode", Message_encode, 1);
         | 
| 564 | 
            -
              rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1);
         | 
| 631 | 
            +
              rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
         | 
| 565 632 | 
             
              rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
         | 
| 566 633 | 
             
              rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
         | 
| 567 634 |  | 
| @@ -631,10 +698,9 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) { | |
| 631 698 | 
             
                const char* name = upb_enum_iter_name(&it);
         | 
| 632 699 | 
             
                int32_t value = upb_enum_iter_number(&it);
         | 
| 633 700 | 
             
                if (name[0] < 'A' || name[0] > 'Z') {
         | 
| 634 | 
            -
                   | 
| 635 | 
            -
             | 
| 636 | 
            -
             | 
| 637 | 
            -
                           name);
         | 
| 701 | 
            +
                  rb_warn("Enum value '%s' does not start with an uppercase letter "
         | 
| 702 | 
            +
                          "as is required for Ruby constants.",
         | 
| 703 | 
            +
                          name);
         | 
| 638 704 | 
             
                }
         | 
| 639 705 | 
             
                rb_define_const(mod, name, INT2NUM(value));
         | 
| 640 706 | 
             
              }
         | 
| @@ -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);
         | 
| @@ -442,10 +491,12 @@ VALUE Map_iter_value(Map_iter* iter); | |
| 442 491 | 
             
            // -----------------------------------------------------------------------------
         | 
| 443 492 |  | 
| 444 493 | 
             
            #define MESSAGE_FIELD_NO_CASE ((size_t)-1)
         | 
| 494 | 
            +
            #define MESSAGE_FIELD_NO_HASBIT ((size_t)-1)
         | 
| 445 495 |  | 
| 446 496 | 
             
            struct MessageField {
         | 
| 447 497 | 
             
              size_t offset;
         | 
| 448 498 | 
             
              size_t case_offset;  // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
         | 
| 499 | 
            +
              size_t hasbit;
         | 
| 449 500 | 
             
            };
         | 
| 450 501 |  | 
| 451 502 | 
             
            struct MessageLayout {
         | 
| @@ -456,6 +507,9 @@ struct MessageLayout { | |
| 456 507 |  | 
| 457 508 | 
             
            MessageLayout* create_layout(const upb_msgdef* msgdef);
         | 
| 458 509 | 
             
            void free_layout(MessageLayout* layout);
         | 
| 510 | 
            +
            bool field_contains_hasbit(MessageLayout* layout,
         | 
| 511 | 
            +
                             const upb_fielddef* field);
         | 
| 512 | 
            +
            VALUE layout_get_default(const upb_fielddef* field);
         | 
| 459 513 | 
             
            VALUE layout_get(MessageLayout* layout,
         | 
| 460 514 | 
             
                             const void* storage,
         | 
| 461 515 | 
             
                             const upb_fielddef* field);
         | 
| @@ -463,6 +517,12 @@ void layout_set(MessageLayout* layout, | |
| 463 517 | 
             
                            void* storage,
         | 
| 464 518 | 
             
                            const upb_fielddef* field,
         | 
| 465 519 | 
             
                            VALUE val);
         | 
| 520 | 
            +
            VALUE layout_has(MessageLayout* layout,
         | 
| 521 | 
            +
                             const void* storage,
         | 
| 522 | 
            +
                             const upb_fielddef* field);
         | 
| 523 | 
            +
            void layout_clear(MessageLayout* layout,
         | 
| 524 | 
            +
                             const void* storage,
         | 
| 525 | 
            +
                             const upb_fielddef* field);
         | 
| 466 526 | 
             
            void layout_init(MessageLayout* layout, void* storage);
         | 
| 467 527 | 
             
            void layout_mark(MessageLayout* layout, void* storage);
         | 
| 468 528 | 
             
            void layout_dup(MessageLayout* layout, void* to, void* from);
         | 
| @@ -512,7 +572,7 @@ VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value); | |
| 512 572 | 
             
            VALUE Message_descriptor(VALUE klass);
         | 
| 513 573 | 
             
            VALUE Message_decode(VALUE klass, VALUE data);
         | 
| 514 574 | 
             
            VALUE Message_encode(VALUE klass, VALUE msg_rb);
         | 
| 515 | 
            -
            VALUE Message_decode_json(VALUE  | 
| 575 | 
            +
            VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass);
         | 
| 516 576 | 
             
            VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
         | 
| 517 577 |  | 
| 518 578 | 
             
            VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb);
         |