static bool upb_fielddef_resolve(upb_fielddef *f, upb_def *def, upb_status *s) { assert(upb_dyncast_unresolveddef(f->def)); upb_def_unref(f->def); f->def = def; if (f->type == UPB_TYPE(ENUM) && f->default_is_symbolic) { // Resolve the enum's default from a string to an integer. upb_byteregion *bytes = upb_value_getbyteregion(f->defaultval); assert(bytes); // Points to either a real default or the empty string. upb_enumdef *e = upb_downcast_enumdef(f->def); int32_t val = 0; // Could do a sanity check that the default value does not have embedded // NULLs. if (upb_byteregion_len(bytes) == 0) { upb_value_setint32(&f->defaultval, e->defaultval); } else { size_t len; // ptr is guaranteed to be NULL-terminated because the byteregion was // created with upb_byteregion_newl(). const char *ptr = upb_byteregion_getptr(bytes, 0, &len); assert(len == upb_byteregion_len(bytes)); // Should all be in one chunk. bool success = upb_enumdef_ntoi(e, ptr, &val); if (!success) { upb_status_seterrf( s, "Default enum value (%s) is not a member of the enum", ptr); return false; } upb_value_setint32(&f->defaultval, val); } upb_byteregion_free(bytes); } return true; }
static bool upb_fielddef_resolve(upb_fielddef *f, upb_def *def, upb_status *s) { assert(upb_dyncast_unresolveddef(f->def)); upb_def_unref(f->def); f->def = def; if (f->type == UPB_TYPE(ENUM) && f->default_is_symbolic) { // Resolve the enum's default from a string to an integer. upb_strref *str = (upb_strref*)upb_value_getstrref(f->defaultval); assert(str); // Should point to either a real default or the empty string. upb_enumdef *e = upb_downcast_enumdef(f->def); int32_t val = 0; // Could do a sanity check that the default value does not have embedded // NULLs. if (str->ptr[0] == '\0') { upb_value_setint32(&f->defaultval, e->defaultval); } else { bool success = upb_enumdef_ntoi(e, str->ptr, &val); if (!success) { upb_status_seterrf( s, "Default enum value (%s) is not a member of the enum", str); return false; } upb_value_setint32(&f->defaultval, val); } upb_strref_free(str); } return true; }
bool upb_fielddef_resolvedefault(upb_fielddef *f) { if (!upb_fielddef_default_is_symbolic(f)) return true; upb_byteregion *bytes = upb_value_getbyteregion(f->defaultval); const upb_enumdef *e = upb_downcast_enumdef(upb_fielddef_subdef(f)); assert(bytes); // Points to either a real default or the empty string. assert(e); if (upb_byteregion_len(bytes) == 0) { // The "default default" for an enum is the first defined value. upb_value_setint32(&f->defaultval, e->defaultval); } else { size_t len; int32_t val = 0; // ptr is guaranteed to be NULL-terminated because the byteregion was // created with upb_byteregion_newl(). const char *ptr = upb_byteregion_getptr( bytes, upb_byteregion_startofs(bytes), &len); assert(len == upb_byteregion_len(bytes)); // Should all be in one chunk if (!upb_enumdef_ntoi(e, ptr, &val)) { return false; } upb_value_setint32(&f->defaultval, val); } f->default_is_string = false; upb_byteregion_free(bytes); return true; }
static void upb_def_free(upb_def *def) { switch (def->type) { case UPB_DEF_MSG: upb_msgdef_free(upb_downcast_msgdef(def)); break; case UPB_DEF_ENUM: upb_enumdef_free(upb_downcast_enumdef(def)); break; case UPB_DEF_UNRESOLVED: upb_unresolveddef_free(upb_downcast_unresolveddef(def)); break; default: assert(false); } }
upb_def *upb_def_dup(const upb_def *def, const void *o) { switch (def->type) { case UPB_DEF_MSG: return upb_upcast(upb_msgdef_dup(upb_downcast_msgdef(def), o)); case UPB_DEF_FIELD: return upb_upcast(upb_fielddef_dup(upb_downcast_fielddef(def), o)); case UPB_DEF_ENUM: return upb_upcast(upb_enumdef_dup(upb_downcast_enumdef(def), o)); default: assert(false); return NULL; } }
static upb_flow_t upb_textprinter_value(void *_p, upb_value fval, upb_value val) { upb_textprinter *p = _p; upb_fielddef *f = upb_value_getfielddef(fval); upb_textprinter_indent(p); CHECK(upb_bytesink_printf(p->bytesink, &p->status, UPB_STRFMT ": ", UPB_STRARG(f->name))); #define CASE(fmtstr, member) \ CHECK(upb_bytesink_printf(p->bytesink, &p->status, fmtstr, upb_value_get ## member(val))); break; switch(f->type) { case UPB_TYPE(DOUBLE): CASE("%0.f", double); case UPB_TYPE(FLOAT): CASE("%0.f", float) case UPB_TYPE(INT64): case UPB_TYPE(SFIXED64): case UPB_TYPE(SINT64): CASE("%" PRId64, int64) case UPB_TYPE(UINT64): case UPB_TYPE(FIXED64): CASE("%" PRIu64, uint64) case UPB_TYPE(UINT32): case UPB_TYPE(FIXED32): CASE("%" PRIu32, uint32); case UPB_TYPE(ENUM): { upb_enumdef *enum_def = upb_downcast_enumdef(f->def); upb_string *enum_label = upb_enumdef_iton(enum_def, upb_value_getint32(val)); if (enum_label) { // We found a corresponding string for this enum. Otherwise we fall // through to the int32 code path. CHECK(upb_bytesink_putstr(p->bytesink, enum_label, &p->status)); break; } } case UPB_TYPE(INT32): case UPB_TYPE(SFIXED32): case UPB_TYPE(SINT32): CASE("%" PRId32, int32) case UPB_TYPE(BOOL): CASE("%hhu", bool); case UPB_TYPE(STRING): case UPB_TYPE(BYTES): CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\""), &p->status)); CHECK(upb_textprinter_putescaped(p, upb_value_getstr(val), f->type == UPB_TYPE(STRING))); CHECK(upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\""), &p->status)); break; } upb_textprinter_endfield(p); return UPB_CONTINUE; err: return UPB_BREAK; }
/* Output a symbolic value from the enum if found, else just print as int32. */ static bool textprinter_putenum(void *closure, const void *handler_data, int32_t val) { upb_textprinter *p = closure; const upb_fielddef *f = handler_data; const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f)); const char *label = upb_enumdef_iton(enum_def, val); if (label) { indent(p); putf(p, "%s: %s", upb_fielddef_name(f), label); endfield(p); } else { if (!textprinter_putint32(closure, handler_data, val)) return false; } return true; }
bool upb_fielddef_resolveenumdefault(upb_fielddef *f, upb_status *s) { if (!upb_fielddef_default_is_symbolic(f)) return true; str_t *str = upb_value_getptr(f->defaultval); const upb_enumdef *e = upb_downcast_enumdef(upb_fielddef_subdef(f)); assert(str); // Points to either a real default or the empty string. assert(e); if (str->len == 0) { // The "default default" for an enum is the first defined value. upb_value_setint32(&f->defaultval, e->defaultval); } else { int32_t val = 0; if (!upb_enumdef_ntoi(e, str->str, &val)) { upb_status_seterrf(s, "enum default not found in enum (%s)", str->str); return false; } upb_value_setint32(&f->defaultval, val); } f->default_is_string = false; freestr(str); return true; }