Esempio n. 1
0
void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
  upb_msg_field_iter it;
  for (upb_msg_field_begin(&it, layout->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);

    void* to_memory = slot_memory(layout, to, field);
    uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
    void* from_memory = slot_memory(layout, from, field);
    uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);

    if (upb_fielddef_containingoneof(field)) {
      if (*from_oneof_case == upb_fielddef_number(field)) {
        *to_oneof_case = *from_oneof_case;
        native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
      }
    } else if (is_map_field(field)) {
      DEREF(to_memory, VALUE) =
          Map_deep_copy(DEREF(from_memory, VALUE));
    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      DEREF(to_memory, VALUE) =
          RepeatedField_deep_copy(DEREF(from_memory, VALUE));
    } else {
      if (field_contains_hasbit(layout, field)) {
        if (!slot_is_hasbit_set(layout, from, field)) continue;
        slot_set_hasbit(layout, to, field);
      }

      native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
    }
  }
}
Esempio n. 2
0
VALUE layout_get(MessageLayout* layout,
                 const void* storage,
                 const upb_fielddef* field) {
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  bool field_set;
  if (field_contains_hasbit(layout, field)) {
    field_set = slot_is_hasbit_set(layout, storage, field);
  } else {
    field_set = true;
  }

  if (upb_fielddef_containingoneof(field)) {
    if (*oneof_case != upb_fielddef_number(field)) {
      return layout_get_default(field);
    }
    return native_slot_get(upb_fielddef_type(field),
                           field_type_class(field),
                           memory);
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    return *((VALUE *)memory);
  } else if (!field_set) {
    return layout_get_default(field);
  } else {
    return native_slot_get(upb_fielddef_type(field),
                           field_type_class(field),
                           memory);
  }
}
Esempio n. 3
0
static void check_map_field_type(VALUE val, const upb_fielddef* field) {
  const upb_fielddef* key_field = map_field_key(field);
  const upb_fielddef* value_field = map_field_value(field);
  Map* self;

  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
      RTYPEDDATA_TYPE(val) != &Map_type) {
    rb_raise(cTypeError, "Expected Map instance");
  }

  self = ruby_to_Map(val);
  if (self->key_type != upb_fielddef_type(key_field)) {
    rb_raise(cTypeError, "Map key type does not match field's key type");
  }
  if (self->value_type != upb_fielddef_type(value_field)) {
    rb_raise(cTypeError, "Map value type does not match field's value type");
  }
  if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
      upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
    if (self->value_type_class !=
        get_def_obj(upb_fielddef_subdef(value_field))) {
      rb_raise(cTypeError,
               "Map value type has wrong message/enum class");
    }
  }
}
Esempio n. 4
0
/**
 * lupb_map_typecheck()
 *
 * Checks that the lupb_map at index |narg| can be safely assigned to the
 * field |f| of the message at index |msg|.  If so, returns a upb_msgval for
 * this map.  Otherwise, raises a Lua error.
 */
static upb_msgval lupb_map_typecheck(lua_State *L, int narg, int msg,
                                     const upb_fielddef *f) {
  lupb_map *lmap = lupb_map_check(L, narg);
  upb_map *map = lmap->map;
  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
  const upb_fielddef *key_field = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
  const upb_fielddef *value_field = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);

  UPB_ASSERT(entry && key_field && value_field);

  if (upb_map_keytype(map) != upb_fielddef_type(key_field)) {
    luaL_error(L, "Map key type invalid");
  }

  if (upb_map_valuetype(map) != upb_fielddef_type(value_field)) {
    luaL_error(L, "Map had incorrect value type (expected: %s, got: %s)",
               upb_fielddef_type(value_field), upb_map_valuetype(map));
  }

  if (upb_map_valuetype(map) == UPB_TYPE_MESSAGE) {
    lupb_msgclass_typecheck(
        L, lupb_msg_msgclassfor(L, msg, upb_fielddef_msgsubdef(value_field)),
        lmap->value_lmsgclass);
  }

  return upb_msgval_map(map);
}
Esempio n. 5
0
VALUE layout_get_default(const upb_fielddef *field) {
  switch (upb_fielddef_type(field)) {
    case UPB_TYPE_FLOAT:   return DBL2NUM(upb_fielddef_defaultfloat(field));
    case UPB_TYPE_DOUBLE:  return DBL2NUM(upb_fielddef_defaultdouble(field));
    case UPB_TYPE_BOOL:
      return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
    case UPB_TYPE_MESSAGE: return Qnil;
    case UPB_TYPE_ENUM: {
      const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
      int32_t num = upb_fielddef_defaultint32(field);
      const char *label = upb_enumdef_iton(enumdef, num);
      if (label) {
        return ID2SYM(rb_intern(label));
      } else {
        return INT2NUM(num);
      }
    }
    case UPB_TYPE_INT32:   return INT2NUM(upb_fielddef_defaultint32(field));
    case UPB_TYPE_INT64:   return LL2NUM(upb_fielddef_defaultint64(field));;
    case UPB_TYPE_UINT32:  return UINT2NUM(upb_fielddef_defaultuint32(field));
    case UPB_TYPE_UINT64:  return ULL2NUM(upb_fielddef_defaultuint64(field));
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      size_t size;
      const char *str = upb_fielddef_defaultstr(field, &size);
      VALUE str_rb = rb_str_new(str, size);

      rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
                 kRubyString8bitEncoding : kRubyStringUtf8Encoding);
      rb_obj_freeze(str_rb);
      return str_rb;
    }
    default: return Qnil;
  }
}
Esempio n. 6
0
static void field_endmsg(void *_r, upb_status *status) {
  upb_descreader *r = _r;
  upb_fielddef *f = r->f;
  // TODO: verify that all required fields were present.
  assert(upb_fielddef_number(f) != 0 && upb_fielddef_name(f) != NULL);
  assert((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));

  if (r->default_string) {
    if (upb_fielddef_issubmsg(f)) {
      upb_status_seterrliteral(status, "Submessages cannot have defaults.");
      return;
    }
    if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE(ENUM)) {
      upb_fielddef_setdefaultcstr(f, r->default_string);
    } else {
      upb_value val;
      upb_value_setptr(&val, NULL);  // Silence inaccurate compiler warnings.
      if (!parse_default(r->default_string, &val, upb_fielddef_type(f))) {
        // We don't worry too much about giving a great error message since the
        // compiler should have ensured this was correct.
        upb_status_seterrliteral(status, "Error converting default value.");
        return;
      }
      upb_fielddef_setdefault(f, val);
    }
  }
}
Esempio n. 7
0
// Set up handlers for a singular field.
static void add_handlers_for_singular_field(upb_handlers *h,
        const upb_fielddef *f,
        size_t offset) {
    switch (upb_fielddef_type(f)) {
    case UPB_TYPE_BOOL:
    case UPB_TYPE_INT32:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_ENUM:
    case UPB_TYPE_FLOAT:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT64:
    case UPB_TYPE_DOUBLE:
        upb_shim_set(h, f, offset, -1);
        break;
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
        bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
        upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
        upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
        upb_handlers_setstartstr(h, f,
                                 is_bytes ? bytes_handler : str_handler,
                                 &attr);
        upb_handlers_setstring(h, f, stringdata_handler, &attr);
        upb_handlerattr_uninit(&attr);
        break;
    }
    case UPB_TYPE_MESSAGE: {
        upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
        upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
        upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
        upb_handlerattr_uninit(&attr);
        break;
    }
    }
}
Esempio n. 8
0
File: def.c Progetto: YauzZ/upb
const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
  assert(f->type_is_set_);
  assert(upb_fielddef_type(f) == UPB_TYPE_STRING ||
         upb_fielddef_type(f) == UPB_TYPE_BYTES ||
         upb_fielddef_type(f) == UPB_TYPE_ENUM);
  if (f->default_is_string) {
    str_t *str = f->defaultval.bytes;
    if (len) *len = str->len;
    return str->str;
  }
  return NULL;
}
Esempio n. 9
0
VALUE field_type_class(const upb_fielddef* field) {
  VALUE type_class = Qnil;
  if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
    VALUE submsgdesc =
        get_def_obj(upb_fielddef_subdef(field));
    type_class = Descriptor_msgclass(submsgdesc);
  } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
    VALUE subenumdesc =
        get_def_obj(upb_fielddef_subdef(field));
    type_class = EnumDescriptor_enummodule(subenumdesc);
  }
  return type_class;
}
Esempio n. 10
0
void layout_set(MessageLayout* layout,
                void* storage,
                const upb_fielddef* field,
                VALUE val) {
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  if (upb_fielddef_containingoneof(field)) {
    if (val == Qnil) {
      // Assigning nil to a oneof field clears the oneof completely.
      *oneof_case = ONEOF_CASE_NONE;
      memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
    } else {
      // The transition between field types for a single oneof (union) slot is
      // somewhat complex because we need to ensure that a GC triggered at any
      // point by a call into the Ruby VM sees a valid state for this field and
      // does not either go off into the weeds (following what it thinks is a
      // VALUE but is actually a different field type) or miss an object (seeing
      // what it thinks is a primitive field but is actually a VALUE for the new
      // field type).
      //
      // In order for the transition to be safe, the oneof case slot must be in
      // sync with the value slot whenever the Ruby VM has been called. Thus, we
      // use native_slot_set_value_and_case(), which ensures that both the value
      // and case number are altered atomically (w.r.t. the Ruby VM).
      native_slot_set_value_and_case(
          upb_fielddef_name(field),
          upb_fielddef_type(field), field_type_class(field),
          memory, val,
          oneof_case, upb_fielddef_number(field));
    }
  } else if (is_map_field(field)) {
    check_map_field_type(val, field);
    DEREF(memory, VALUE) = val;
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    check_repeated_field_type(val, field);
    DEREF(memory, VALUE) = val;
  } else {
    native_slot_set(upb_fielddef_name(field),
                    upb_fielddef_type(field), field_type_class(field),
                    memory, val);
  }

  if (layout->fields[upb_fielddef_index(field)].hasbit !=
      MESSAGE_FIELD_NO_HASBIT) {
    slot_set_hasbit(layout, storage, field);
  }
}
Esempio n. 11
0
/**
 * lupb_msg_index
 *
 * Handles:
 *   msg.foo
 *   msg["foo"]
 *   msg[field_descriptor]  # (for extensions) (TODO)
 */
static int lupb_msg_index(lua_State *L) {
  lupb_msg *lmsg = lupb_msg_check(L, 1);
  const upb_fielddef *f = lupb_msg_checkfield(L, lmsg, 2);
  const upb_msglayout *l = lmsg->lmsgclass->layout;

  if (in_userval(f)) {
    lupb_uservalgeti(L, 1, lupb_fieldindex(f));

    if (lua_isnil(L, -1)) {
      /* Check if we need to lazily create wrapper. */
      if (upb_fielddef_isseq(f)) {
        /* TODO(haberman) */
      } else if (upb_fielddef_issubmsg(f)) {
        /* TODO(haberman) */
      } else {
        UPB_ASSERT(upb_fielddef_isstring(f));
        if (upb_msg_has(lmsg->msg, f, l)) {
          upb_msgval val = upb_msg_get(lmsg->msg, f, l);
          lua_pop(L, 1);
          lua_pushlstring(L, val.str.ptr, val.str.len);
          lupb_uservalseti(L, 1, lupb_fieldindex(f), -1);
        }
      }
    }
  } else {
    lupb_pushmsgval(L, upb_fielddef_type(f), upb_msg_get(lmsg->msg, f, l));
  }

  return 1;
}
Esempio n. 12
0
static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
  if (upb_fielddef_isseq(f)) {
    return sizeof(void*);
  } else {
    return upb_msgval_sizeof2(upb_fielddef_type(f));
  }
}
Esempio n. 13
0
File: shim.c Progetto: YauzZ/upb
bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
                  int32_t hasbit) {
  upb_shim_data *d = malloc(sizeof(*d));
  if (!d) return false;
  d->offset = offset;
  d->hasbit = hasbit;

  upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
  upb_handlerattr_sethandlerdata(&attr, d, free);
  upb_handlerattr_setalwaysok(&attr, true);

#define TYPE(u, l) \
  case UPB_TYPE_##u: \
    ok = upb_handlers_set##l(h, f, upb_shim_set##l, &attr); break;

  bool ok = false;

  switch (upb_fielddef_type(f)) {
    TYPE(INT64,  int64);
    TYPE(INT32,  int32);
    TYPE(ENUM,   int32);
    TYPE(UINT64, uint64);
    TYPE(UINT32, uint32);
    TYPE(DOUBLE, double);
    TYPE(FLOAT,  float);
    TYPE(BOOL,   bool);
    default: assert(false); break;
  }
#undef TYPE

  upb_handlerattr_uninit(&attr);
  return ok;
}
Esempio n. 14
0
/*
 * call-seq:
 *     FieldDescriptor.type => type
 *
 * Returns this field's type, as a Ruby symbol, or nil if not yet set.
 *
 * Valid field types are:
 *     :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string,
 *     :bytes, :message.
 */
VALUE FieldDescriptor_type(VALUE _self) {
  DEFINE_SELF(FieldDescriptor, self, _self);
  if (!upb_fielddef_typeisset(self->fielddef)) {
    return Qnil;
  }
  return fieldtype_to_ruby(upb_fielddef_type(self->fielddef));
}
Esempio n. 15
0
/**
 * lupb_msg_newindex()
 *
 * Handles:
 *   msg.foo = bar
 *   msg["foo"] = bar
 *   msg[field_descriptor] = bar  # (for extensions) (TODO)
 */
static int lupb_msg_newindex(lua_State *L) {
  lupb_msg *lmsg = lupb_msg_check(L, 1);
  const upb_fielddef *f = lupb_msg_checkfield(L, lmsg, 2);
  upb_fieldtype_t type = upb_fielddef_type(f);
  upb_msgval msgval;

  /* Typecheck and get msgval. */

  if (upb_fielddef_isseq(f)) {
    msgval = lupb_array_typecheck(L, 3, 1, f);
  } else if (upb_fielddef_ismap(f)) {
    msgval = lupb_map_typecheck(L, 3, 1, f);
  } else {
    const lupb_msgclass *lmsgclass = NULL;

    if (type == UPB_TYPE_MESSAGE) {
      lmsgclass = lupb_msg_getsubmsgclass(L, 1, f);
    }

    msgval = lupb_tomsgval(L, type, 3, lmsgclass);
  }

  /* Set in upb_msg and userval (if necessary). */

  upb_msg_set(lmsg->msg, f, msgval, lmsg->lmsgclass->layout);

  if (in_userval(f)) {
    lupb_uservalseti(L, 1, lupb_fieldindex(f), 3);
  }

  return 0;  /* 1 for chained assignments? */
}
Esempio n. 16
0
static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
                   int depth) {
  if (map == Qnil) return;
  Map* self = ruby_to_Map(map);

  upb_sink subsink;

  upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);

  assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
  const upb_fielddef* key_field = map_field_key(f);
  const upb_fielddef* value_field = map_field_value(f);

  Map_iter it;
  for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
    VALUE key = Map_iter_key(&it);
    VALUE value = Map_iter_value(&it);

    upb_sink entry_sink;
    upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
                         &entry_sink);
    upb_sink_startmsg(&entry_sink);

    put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink);
    put_ruby_value(value, value_field, self->value_type_class, depth + 1,
                   &entry_sink);

    upb_status status;
    upb_sink_endmsg(&entry_sink, &status);
    upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
  }

  upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
}
Esempio n. 17
0
File: def.c Progetto: YauzZ/upb
void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t value) {
  if ((upb_fielddef_type(f) == UPB_TYPE_ENUM &&
       checksetdefault(f, UPB_TYPE_ENUM)) ||
      checksetdefault(f, UPB_TYPE_INT32)) {
    f->defaultval.sint = value;
  }
}
Esempio n. 18
0
File: reader.c Progetto: YauzZ/upb
static bool field_endmsg(void *closure, const void *hd, upb_status *status) {
  UPB_UNUSED(hd);
  upb_descreader *r = closure;
  upb_fielddef *f = r->f;
  // TODO: verify that all required fields were present.
  assert(upb_fielddef_number(f) != 0);
  assert(upb_fielddef_name(f) != NULL);
  assert((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));

  if (r->default_string) {
    if (upb_fielddef_issubmsg(f)) {
      upb_status_seterrmsg(status, "Submessages cannot have defaults.");
      return false;
    }
    if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) {
      upb_fielddef_setdefaultcstr(f, r->default_string, NULL);
    } else {
      if (r->default_string && !parse_default(r->default_string, f)) {
        // We don't worry too much about giving a great error message since the
        // compiler should have ensured this was correct.
        upb_status_seterrmsg(status, "Error converting default value.");
        return false;
      }
    }
  }
  return true;
}
Esempio n. 19
0
File: def.c Progetto: Phuehvk/upb
upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
  upb_fielddef *newf = upb_fielddef_new(owner);
  if (!newf) return NULL;
  upb_fielddef_settype(newf, upb_fielddef_type(f));
  upb_fielddef_setlabel(newf, upb_fielddef_label(f));
  upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL);
  upb_fielddef_setname(newf, upb_fielddef_name(f), NULL);
  if (f->default_is_string) {
    str_t *s = upb_value_getptr(upb_fielddef_default(f));
    upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL);
  } else {
    upb_fielddef_setdefault(newf, upb_fielddef_default(f));
  }

  const char *srcname;
  if (f->subdef_is_symbolic) {
    srcname = f->sub.name;  // Might be NULL.
  } else {
    srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
  }
  if (srcname) {
    char *newname = malloc(strlen(f->sub.def->fullname) + 2);
    if (!newname) {
      upb_fielddef_unref(newf, owner);
      return NULL;
    }
    strcpy(newname, ".");
    strcat(newname, f->sub.def->fullname);
    upb_fielddef_setsubdefname(newf, newname, NULL);
    free(newname);
  }

  return newf;
}
Esempio n. 20
0
static VALUE value_from_default(const upb_fielddef *field) {
  switch (upb_fielddef_type(field)) {
    case UPB_TYPE_FLOAT:   return DBL2NUM(upb_fielddef_defaultfloat(field));
    case UPB_TYPE_DOUBLE:  return DBL2NUM(upb_fielddef_defaultdouble(field));
    case UPB_TYPE_BOOL:
      return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
    case UPB_TYPE_MESSAGE: return Qnil;
    case UPB_TYPE_ENUM: {
      const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
      int32_t num = upb_fielddef_defaultint32(field);
      const char *label = upb_enumdef_iton(enumdef, num);
      if (label) {
        return ID2SYM(rb_intern(label));
      } else {
        return INT2NUM(num);
      }
    }
    case UPB_TYPE_INT32:   return INT2NUM(upb_fielddef_defaultint32(field));
    case UPB_TYPE_INT64:   return LL2NUM(upb_fielddef_defaultint64(field));;
    case UPB_TYPE_UINT32:  return UINT2NUM(upb_fielddef_defaultuint32(field));
    case UPB_TYPE_UINT64:  return ULL2NUM(upb_fielddef_defaultuint64(field));
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      size_t size;
      const char *str = upb_fielddef_defaultstr(field, &size);
      return rb_str_new(str, size);
    }
    default: return Qnil;
  }
}
Esempio n. 21
0
File: upb.c Progetto: chenbk85/upb
static PyObject *PyUpb_FieldDef_getattro(PyObject *obj, PyObject *attr_name) {
  upb_fielddef *f = Check_FieldDef(obj, NULL);
  if (!upb_fielddef_ismutable(f)) {
    PyErr_SetString(PyExc_TypeError, "fielddef is not mutable.");
    return NULL;
  }
  const char *name = PyString_AsString(attr_name);
  if (streql(name, "name")) {
    const char *name = upb_fielddef_name(f);
    return name == NULL ? Py_None : PyString_FromString(name);
  } else if (streql(name, "number")) {
    uint32_t num = upb_fielddef_number(f);
    return num == 0 ? Py_None : PyInt_FromLong(num);
  } else if (streql(name, "type")) {
    uint8_t type = upb_fielddef_type(f);
    return type == 0 ? Py_None : PyInt_FromLong(type);
  } else if (streql(name, "label")) {
    return PyInt_FromLong(upb_fielddef_label(f));
  } else if (streql(name, "type_name")) {
    const char *name = upb_fielddef_typename(f);
    return name == NULL ? Py_None : PyString_FromString(name);
  } else if (streql(name, "subdef")) {
    // NYI;
    return NULL;
  } else if (streql(name, "msgdef")) {
    // NYI;
    return NULL;
  } else {
    return PyUpb_Error("Invalid fielddef member.");
  }
}
Esempio n. 22
0
static void upb_fielddef_init_default(upb_fielddef *f) {
  f->default_is_string = false;
  switch (upb_fielddef_type(f)) {
    case UPB_TYPE(DOUBLE): upb_value_setdouble(&f->defaultval, 0); break;
    case UPB_TYPE(FLOAT): upb_value_setfloat(&f->defaultval, 0); break;
    case UPB_TYPE(UINT64):
    case UPB_TYPE(FIXED64): upb_value_setuint64(&f->defaultval, 0); break;
    case UPB_TYPE(INT64):
    case UPB_TYPE(SFIXED64):
    case UPB_TYPE(SINT64): upb_value_setint64(&f->defaultval, 0); break;
    case UPB_TYPE(ENUM):
    case UPB_TYPE(INT32):
    case UPB_TYPE(SINT32):
    case UPB_TYPE(SFIXED32): upb_value_setint32(&f->defaultval, 0); break;
    case UPB_TYPE(UINT32):
    case UPB_TYPE(FIXED32): upb_value_setuint32(&f->defaultval, 0); break;
    case UPB_TYPE(BOOL): upb_value_setbool(&f->defaultval, false); break;
    case UPB_TYPE(STRING):
    case UPB_TYPE(BYTES):
        upb_value_setbyteregion(&f->defaultval, upb_byteregion_new(""));
        f->default_is_string = true;
        break;
    case UPB_TYPE(GROUP):
    case UPB_TYPE(MESSAGE): upb_value_setptr(&f->defaultval, NULL); break;
    case UPB_TYPE_NONE: break;
  }
}
Esempio n. 23
0
static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
  RepeatedField* self;
  assert(upb_fielddef_label(field) == UPB_LABEL_REPEATED);

  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
      RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
    rb_raise(cTypeError, "Expected repeated field array");
  }

  self = ruby_to_RepeatedField(val);
  if (self->field_type != upb_fielddef_type(field)) {
    rb_raise(cTypeError, "Repeated field array has wrong element type");
  }

  if (self->field_type == UPB_TYPE_MESSAGE) {
    if (self->field_type_class !=
        Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
      rb_raise(cTypeError,
               "Repeated field array has wrong message class");
    }
  }


  if (self->field_type == UPB_TYPE_ENUM) {
    if (self->field_type_class !=
        EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
      rb_raise(cTypeError,
               "Repeated field array has wrong enum class");
    }
  }
}
Esempio n. 24
0
/*
 * call-seq:
 *     Message.to_h => {}
 *
 * Returns the message as a Ruby Hash object, with keys as symbols.
 */
VALUE Message_to_h(VALUE _self) {
  MessageHeader* self;
  VALUE hash;
  upb_msg_field_iter it;
  TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);

  hash = rb_hash_new();

  for (upb_msg_field_begin(&it, self->descriptor->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);

    // For proto2, do not include fields which are not set.
    if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
	field_contains_hasbit(self->descriptor->layout, field) &&
	!layout_has(self->descriptor->layout, Message_data(self), field)) {
      continue;
    }

    VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
                                 field);
    VALUE msg_key   = ID2SYM(rb_intern(upb_fielddef_name(field)));
    if (is_map_field(field)) {
      msg_value = Map_to_h(msg_value);
    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      msg_value = RepeatedField_to_ary(msg_value);
      if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 &&
          RARRAY_LEN(msg_value) == 0) {
        continue;
      }

      if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
        for (int i = 0; i < RARRAY_LEN(msg_value); i++) {
          VALUE elem = rb_ary_entry(msg_value, i);
          rb_ary_store(msg_value, i, Message_to_h(elem));
        }
      }

    } else if (msg_value != Qnil &&
               upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
      msg_value = Message_to_h(msg_value);
    }
    rb_hash_aset(hash, msg_key, msg_value);
  }
  return hash;
}
Esempio n. 25
0
/**
 * lupb_array_typecheck()
 *
 * Verifies that the lupb_array object at index |narg| can be safely assigned
 * to the field |f| of the lupb_msg object at index |msg|.  If this is safe,
 * returns a upb_msgval representing the array.  Otherwise, throws a Lua error.
 */
static upb_msgval lupb_array_typecheck(lua_State *L, int narg, int msg,
                                       const upb_fielddef *f) {
  lupb_array *larray = lupb_array_check(L, narg);

  if (upb_array_type(larray->arr) != upb_fielddef_type(f) ||
      lupb_msg_getsubmsgclass(L, msg, f) != larray->lmsgclass) {
    luaL_error(L, "Array had incorrect type (expected: %d, got: %d)",
               (int)upb_fielddef_type(f), (int)upb_array_type(larray->arr));
  }

  if (upb_array_type(larray->arr) == UPB_TYPE_MESSAGE) {
    lupb_msgclass_typecheck(L, lupb_msg_getsubmsgclass(L, msg, f),
                            larray->lmsgclass);
  }

  return upb_msgval_arr(larray->arr);
}
Esempio n. 26
0
/**
 * lupb_msgclass_getsubmsgclass()
 *
 * Given a MessageClass at index |narg| and the submessage field |f|, returns
 * the message class for this field.
 *
 * Currently we do a hash table lookup for this.  If we wanted we could try to
 * optimize this by caching these pointers in our msgclass, in an array indexed
 * by field index.  We would still need to fall back to calling msgclassfor(),
 * unless we wanted to eagerly create message classes for all submessages.  But
 * for big schemas that might be a lot of things to build, and we might end up
 * not using most of them. */
static const lupb_msgclass *lupb_msgclass_getsubmsgclass(lua_State *L, int narg,
                                                         const upb_fielddef *f) {
  if (upb_fielddef_type(f) != UPB_TYPE_MESSAGE) {
    return NULL;
  }

  return lupb_msgclass_msgclassfor(L, narg, upb_fielddef_msgsubdef(f));
}
Esempio n. 27
0
bool is_map_field(const upb_fielddef* field) {
    if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
            upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
        return false;
    }
    const upb_msgdef* subdef = upb_fielddef_msgsubdef(field);
    return upb_msgdef_mapentry(subdef);
}
Esempio n. 28
0
static void onmreg(const void *c, upb_handlers *h) {
  const upb_msgdef *m = upb_handlers_msgdef(h);
  upb_msg_field_iter i;
  UPB_UNUSED(c);

  upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
  upb_handlers_setendmsg(h, textprinter_endmsg, NULL);

  for(upb_msg_field_begin(&i, m);
      !upb_msg_field_done(&i);
      upb_msg_field_next(&i)) {
    upb_fielddef *f = upb_msg_iter_field(&i);
    upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
    upb_handlerattr_sethandlerdata(&attr, f);
    switch (upb_fielddef_type(f)) {
      case UPB_TYPE_INT32:
        upb_handlers_setint32(h, f, textprinter_putint32, &attr);
        break;
      case UPB_TYPE_INT64:
        upb_handlers_setint64(h, f, textprinter_putint64, &attr);
        break;
      case UPB_TYPE_UINT32:
        upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
        break;
      case UPB_TYPE_UINT64:
        upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
        break;
      case UPB_TYPE_FLOAT:
        upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
        break;
      case UPB_TYPE_DOUBLE:
        upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
        break;
      case UPB_TYPE_BOOL:
        upb_handlers_setbool(h, f, textprinter_putbool, &attr);
        break;
      case UPB_TYPE_STRING:
      case UPB_TYPE_BYTES:
        upb_handlers_setstartstr(h, f, textprinter_startstr, &attr);
        upb_handlers_setstring(h, f, textprinter_putstr, &attr);
        upb_handlers_setendstr(h, f, textprinter_endstr, &attr);
        break;
      case UPB_TYPE_MESSAGE: {
        const char *name =
            upb_fielddef_istagdelim(f)
                ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
                : upb_fielddef_name(f);
        upb_handlerattr_sethandlerdata(&attr, name);
        upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
        upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
        break;
      }
      case UPB_TYPE_ENUM:
        upb_handlers_setint32(h, f, textprinter_putenum, &attr);
        break;
    }
  }
}
Esempio n. 29
0
// Allocates a new map_handlerdata_t given the map entry message definition. If
// the offset of the field within the parent message is also given, that is
// added to the handler data as well. Note that this is called *twice* per map
// field: once in the parent message handler setup when setting the startsubmsg
// handler and once in the map entry message handler setup when setting the
// key/value and endmsg handlers. The reason is that there is no easy way to
// pass the handlerdata down to the sub-message handler setup.
static map_handlerdata_t* new_map_handlerdata(
    size_t ofs,
    const upb_msgdef* mapentry_def,
    Descriptor* desc) {
    const upb_fielddef* key_field;
    const upb_fielddef* value_field;
    map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
    hd->ofs = ofs;
    key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
    assert(key_field != NULL);
    hd->key_field_type = upb_fielddef_type(key_field);
    value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
    assert(value_field != NULL);
    hd->value_field_type = upb_fielddef_type(value_field);
    hd->value_field_subdef = upb_fielddef_subdef(value_field);

    return hd;
}
Esempio n. 30
0
const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) {
  const upb_msgdef* subdef;
  if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
      upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
    return NULL;
  }
  subdef = upb_fielddef_msgsubdef(field);
  return upb_msgdef_mapentry(subdef) ? subdef : NULL;
}