summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2018-12-20 09:53:13 -0800
committerJoshua Haberman <jhaberman@gmail.com>2018-12-20 09:53:13 -0800
commit8afe0b03a349cc259fb731ff2d2e0a13e47c166a (patch)
tree65979d391852682c5572a2d93c6534da67e7d7ec /upb
parent549a828f76bfbc42276797ca5eef2c1f730b0d1f (diff)
Some fixes for Ruby.
Diffstat (limited to 'upb')
-rw-r--r--upb/def.c55
-rw-r--r--upb/def.h3
-rw-r--r--upb/msgfactory.c9
3 files changed, 55 insertions, 12 deletions
diff --git a/upb/def.c b/upb/def.c
index ccbf407..83e5a99 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -355,6 +355,10 @@ const char *upb_enumdef_name(const upb_enumdef *e) {
return shortdefname(e->full_name);
}
+const upb_filedef *upb_enumdef_file(const upb_enumdef *e) {
+ return e->file;
+}
+
int32_t upb_enumdef_default(const upb_enumdef *e) {
UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
return e->defaultval;
@@ -606,6 +610,12 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) {
return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
}
+bool upb_fielddef_haspresence(const upb_fielddef *f) {
+ if (upb_fielddef_isseq(f)) return false;
+ if (upb_fielddef_issubmsg(f)) return true;
+ return f->file->syntax == UPB_SYNTAX_PROTO2;
+}
+
static bool between(int32_t x, int32_t low, int32_t high) {
return x >= low && x <= high;
}
@@ -624,6 +634,10 @@ const char *upb_msgdef_fullname(const upb_msgdef *m) {
return m->full_name;
}
+const upb_filedef *upb_msgdef_file(const upb_msgdef *m) {
+ return m->file;
+}
+
const char *upb_msgdef_name(const upb_msgdef *m) {
return shortdefname(m->full_name);
}
@@ -1166,6 +1180,12 @@ static bool create_fielddef(
* to the field_proto until later when we can properly resolve it. */
f->sub.unresolved = field_proto;
+ if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
+ upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)",
+ f->full_name);
+ return false;
+ }
+
if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
int oneof_index =
google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
@@ -1229,6 +1249,13 @@ static bool create_enumdef(
values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
+ if (n == 0) {
+ upb_status_seterrf(ctx->status,
+ "enums must contain at least one value (%s)",
+ e->full_name);
+ return false;
+ }
+
for (i = 0; i < n; i++) {
const google_protobuf_EnumValueDescriptorProto *value = values[i];
upb_stringview name = google_protobuf_EnumValueDescriptorProto_name(value);
@@ -1236,6 +1263,13 @@ static bool create_enumdef(
int32_t num = google_protobuf_EnumValueDescriptorProto_number(value);
upb_value v = upb_value_int32(num);
+ if (n == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
+ upb_status_seterrf(ctx->status,
+ "for proto3, the first enum value must be zero (%s)",
+ e->full_name);
+ return false;
+ }
+
if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2);
return false;
@@ -1399,9 +1433,24 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
upb_stringview defaultval =
google_protobuf_FieldDescriptorProto_default_value(field_proto);
+
+ if (f->file->syntax == UPB_SYNTAX_PROTO3) {
+ upb_status_seterrf(ctx->status,
+ "proto3 fields cannot have explicit defaults (%s)",
+ f->full_name);
+ return false;
+ }
+
+ if (upb_fielddef_issubmsg(f)) {
+ upb_status_seterrf(ctx->status,
+ "message fields cannot have explicit defaults (%s)",
+ f->full_name);
+ return false;
+ }
+
if (!parse_default(ctx, defaultval.data, defaultval.size, f)) {
- upb_status_seterrf(ctx->status, "bad default '" UPB_STRINGVIEW_FORMAT "'",
- UPB_STRINGVIEW_ARGS(defaultval));
+ upb_status_seterrf(ctx->status, "couldn't parse default for field (%s)",
+ f->full_name);
return false;
}
}
@@ -1532,7 +1581,7 @@ static bool build_filedef(
}
return true;
-}
+ }
static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx,
upb_status *status) {
diff --git a/upb/def.h b/upb/def.h
index e6fdf21..8664fb5 100644
--- a/upb/def.h
+++ b/upb/def.h
@@ -202,6 +202,7 @@ float upb_fielddef_defaultfloat(const upb_fielddef *f);
double upb_fielddef_defaultdouble(const upb_fielddef *f);
const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len);
bool upb_fielddef_hassubdef(const upb_fielddef *f);
+bool upb_fielddef_haspresence(const upb_fielddef *f);
const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f);
const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f);
@@ -349,6 +350,7 @@ class upb::MessageDef {
UPB_BEGIN_EXTERN_C
const char *upb_msgdef_fullname(const upb_msgdef *m);
+const upb_filedef *upb_msgdef_file(const upb_msgdef *m);
const char *upb_msgdef_name(const upb_msgdef *m);
int upb_msgdef_numoneofs(const upb_msgdef *m);
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m);
@@ -485,6 +487,7 @@ UPB_BEGIN_EXTERN_C
const char *upb_enumdef_fullname(const upb_enumdef *e);
const char *upb_enumdef_name(const upb_enumdef *e);
+const upb_filedef *upb_enumdef_file(const upb_enumdef *e);
int32_t upb_enumdef_default(const upb_enumdef *e);
int upb_enumdef_numvals(const upb_enumdef *e);
diff --git a/upb/msgfactory.c b/upb/msgfactory.c
index 73347b8..63df49e 100644
--- a/upb/msgfactory.c
+++ b/upb/msgfactory.c
@@ -46,15 +46,6 @@ static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
}
}
-static bool upb_fielddef_haspresence(const upb_fielddef *f) {
- if (upb_fielddef_isseq(f)) return false;
- if (upb_fielddef_issubmsg(f)) return true;
-
- /* Primitive field: return true unless there is a message that specifies
- * presence should not exist. */
- return upb_msgdef_syntax(upb_fielddef_containingtype(f)) == UPB_SYNTAX_PROTO2;
-}
-
/** upb_msglayout *************************************************************/
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback