Example #1
0
File: def.c Project: YauzZ/upb
static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
                       void *closure) {
  const upb_fielddef *f = (const upb_fielddef*)r;
  if (upb_fielddef_containingtype(f)) {
    visit(r, UPB_UPCAST2(upb_fielddef_containingtype(f)), closure);
  }
  if (upb_fielddef_subdef(f)) {
    visit(r, UPB_UPCAST(upb_fielddef_subdef(f)), closure);
  }
}
Example #2
0
/*
 * call-seq:
 *     FieldDescriptor.get(message) => value
 *
 * Returns the value set for this field on the given message. Raises an
 * exception if message is of the wrong type.
 */
VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) {
  DEFINE_SELF(FieldDescriptor, self, _self);
  MessageHeader* msg;
  TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
  if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) {
    rb_raise(rb_eTypeError, "get method called on wrong message type");
  }
  return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef);
}
Example #3
0
File: def.c Project: YauzZ/upb
bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
  if (upb_fielddef_containingtype(f)) {
    upb_status_seterrmsg(
        s, "cannot change field number after adding to a message");
    return false;
  }
  if (number == 0 || number > UPB_MAX_FIELDNUMBER) {
    upb_status_seterrf(s, "invalid field number (%u)", number);
    return false;
  }
  f->number_ = number;
  return true;
}
Example #4
0
File: def.c Project: YauzZ/upb
bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
                                        upb_status *s) {
  assert(!upb_fielddef_isfrozen(f));
  if (upb_fielddef_containingtype(f)) {
    upb_status_seterrmsg(s, "field has already been added to a message.");
    return false;
  }
  // TODO: validate name (upb_isident() doesn't quite work atm because this name
  // may have a leading ".").
  release_containingtype(f);
  f->msg.name = upb_strdup(name);
  f->msg_is_symbolic = true;
  return true;
}
Example #5
0
File: def.c Project: YauzZ/upb
bool upb_msgdef_addfields(upb_msgdef *m, upb_fielddef *const *fields, int n,
                          const void *ref_donor, upb_status *s) {
  // TODO: extensions need to have a separate namespace, because proto2 allows a
  // top-level extension (ie. one not in any package) to have the same name as a
  // field from the message.
  //
  // This also implies that there needs to be a separate lookup-by-name method
  // for extensions.  It seems desirable for iteration to return both extensions
  // and non-extensions though.
  //
  // We also need to validate that the field number is in an extension range iff
  // it is an extension.

  // Check constraints for all fields before performing any action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    // TODO(haberman): handle the case where two fields of the input duplicate
    // name or number.
    if (upb_fielddef_containingtype(f) != NULL) {
      upb_status_seterrmsg(s, "fielddef already belongs to a message");
      return false;
    } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
      upb_status_seterrmsg(s, "field name or number were not set");
      return false;
    } else if(upb_msgdef_itof(m, upb_fielddef_number(f)) ||
              upb_msgdef_ntof(m, upb_fielddef_name(f))) {
      upb_status_seterrmsg(s, "duplicate field name or number");
      return false;
    }
  }

  // Constraint checks ok, perform the action.
  for (int i = 0; i < n; i++) {
    upb_fielddef *f = fields[i];
    release_containingtype(f);
    f->msg.def = m;
    f->msg_is_symbolic = false;
    upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
    upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
    upb_ref2(f, m);
    upb_ref2(m, f);
    if (ref_donor) upb_fielddef_unref(f, ref_donor);
  }
  return true;
}
Example #6
0
File: handlers.c Project: YauzZ/upb
static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
                         upb_handlertype_t type) {
  upb_selector_t sel;
  assert(!upb_handlers_isfrozen(h));
  if (upb_handlers_msgdef(h) != upb_fielddef_containingtype(f)) {
    upb_status_seterrf(
        &h->status_, "type mismatch: field %s does not belong to message %s",
        upb_fielddef_name(f), upb_msgdef_fullname(upb_handlers_msgdef(h)));
    return -1;
  }
  if (!upb_handlers_getselector(f, type, &sel)) {
    upb_status_seterrf(
        &h->status_,
        "type mismatch: cannot register handler type %d for field %s",
        type, upb_fielddef_name(f));
    return -1;
  }
  return sel;
}
Example #7
0
File: handlers.c Project: YauzZ/upb
bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
                              upb_selector_t *s) {
  switch (type) {
    case UPB_HANDLER_INT32:
    case UPB_HANDLER_INT64:
    case UPB_HANDLER_UINT32:
    case UPB_HANDLER_UINT64:
    case UPB_HANDLER_FLOAT:
    case UPB_HANDLER_DOUBLE:
    case UPB_HANDLER_BOOL:
      if (!upb_fielddef_isprimitive(f) ||
          upb_handlers_getprimitivehandlertype(f) != type)
        return false;
      *s = f->selector_base;
      break;
    case UPB_HANDLER_STRING:
      if (upb_fielddef_isstring(f)) {
        *s = f->selector_base;
      } else if (upb_fielddef_issubmsg(f)) {
        *s = f->selector_base + 3;
      } else {
        return false;
      }
      break;
    case UPB_HANDLER_STARTSTR:
      if (upb_fielddef_isstring(f) || upb_fielddef_issubmsg(f)) {
        *s = f->selector_base + 1;
      } else {
        return false;
      }
      break;
    case UPB_HANDLER_ENDSTR:
      if (upb_fielddef_isstring(f) || upb_fielddef_issubmsg(f)) {
        *s = f->selector_base + 2;
      } else {
        return false;
      }
      break;
    case UPB_HANDLER_STARTSEQ:
      if (!upb_fielddef_isseq(f)) return false;
      *s = f->selector_base - 2;
      break;
    case UPB_HANDLER_ENDSEQ:
      if (!upb_fielddef_isseq(f)) return false;
      *s = f->selector_base - 1;
      break;
    case UPB_HANDLER_STARTSUBMSG:
      if (!upb_fielddef_issubmsg(f)) return false;
      // Selectors for STARTSUBMSG are at the beginning of the table so that the
      // selector can also be used as an index into the "sub" array of
      // subhandlers.  The indexes for the two into these two tables are the
      // same, except that in the handler table the static selectors come first.
      *s = f->index_ + UPB_STATIC_SELECTOR_COUNT;
      break;
    case UPB_HANDLER_ENDSUBMSG:
      if (!upb_fielddef_issubmsg(f)) return false;
      *s = f->selector_base;
      break;
  }
  assert(*s < upb_fielddef_containingtype(f)->selector_count);
  return true;
}
Example #8
0
File: def.c Project: YauzZ/upb
upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) {
  return (upb_msgdef*)upb_fielddef_containingtype(f);
}