@@ -1133,25 +1133,38 @@ CheckedError Parser::ParseField(StructDef& struct_def) {
11331133 }
11341134 }
11351135
1136- // For historical convenience reasons, string keys are assumed required.
1137- // Scalars are kDefault unless otherwise specified.
1138- // Nonscalars are kOptional unless required;
11391136 field->key = field->attributes .Lookup (" key" ) != nullptr ;
1140- const bool required = field->attributes .Lookup (" required" ) != nullptr ||
1141- (IsString (type) && field->key );
1142- const bool default_str_or_vec =
1143- ((IsString (type) || IsVector (type)) && field->value .constant != " 0" );
1144- const bool optional = IsScalar (type.base_type )
1145- ? (field->value .constant == " null" )
1146- : !(required || default_str_or_vec);
1147- if (required && optional) {
1148- return Error (" Fields cannot be both optional and required." );
1149- }
1150- field->presence = FieldDef::MakeFieldPresence (optional, required);
11511137
1152- if (required && (struct_def.fixed || IsScalar (type.base_type ))) {
1153- return Error (" only non-scalar fields in tables may be 'required'" );
1138+ if (!struct_def.fixed ) {
1139+ // For historical convenience reasons, string keys are assumed required.
1140+ // Scalars are kDefault unless otherwise specified.
1141+ // Nonscalars are kOptional unless required;
1142+ const bool required = field->attributes .Lookup (" required" ) != nullptr ||
1143+ (IsString (type) && field->key );
1144+ const bool default_str_or_vec =
1145+ ((IsString (type) || IsVector (type)) && field->value .constant != " 0" );
1146+ const bool optional = IsScalar (type.base_type )
1147+ ? (field->value .constant == " null" )
1148+ : !(required || default_str_or_vec);
1149+ if (required && optional) {
1150+ return Error (" Fields cannot be both optional and required." );
1151+ }
1152+ field->presence = FieldDef::MakeFieldPresence (optional, required);
1153+
1154+ if (required && IsScalar (type.base_type )) {
1155+ return Error (" only non-scalar fields in tables may be 'required'" );
1156+ }
1157+ } else {
1158+ // all struct fields are required
1159+ field->presence = FieldDef::kDefault ;
1160+
1161+ // setting required or optional on a struct field is meaningless
1162+ if (field->attributes .Lookup (" required" ) != nullptr ||
1163+ field->attributes .Lookup (" optional" ) != nullptr ) {
1164+ return Error (" struct fields are always required" );
1165+ }
11541166 }
1167+
11551168 if (field->key ) {
11561169 if (struct_def.has_key ) return Error (" only one field may be set as 'key'" );
11571170 struct_def.has_key = true ;
@@ -1188,6 +1201,23 @@ CheckedError Parser::ParseField(StructDef& struct_def) {
11881201 }
11891202 }
11901203
1204+ auto check_enum = [this ](const FieldDef* field, const Type& type,
1205+ const std::string& name,
1206+ const std::string& constant) -> CheckedError {
1207+ // Optional and bitflags enums may have default constants that are not
1208+ // their specified variants.
1209+ if (!field->IsOptional () &&
1210+ type.enum_def ->attributes .Lookup (" bit_flags" ) == nullptr ) {
1211+ if (type.enum_def ->FindByValue (constant) == nullptr ) {
1212+ return Error (" default value of `" + constant + " ` for " + " field `" +
1213+ name + " ` is not part of enum `" + type.enum_def ->name +
1214+ " `." );
1215+ }
1216+ }
1217+
1218+ return NoError ();
1219+ };
1220+
11911221 if (type.enum_def ) {
11921222 // Verify the enum's type and default value.
11931223 const std::string& constant = field->value .constant ;
@@ -1203,19 +1233,19 @@ CheckedError Parser::ParseField(StructDef& struct_def) {
12031233 if (constant != " 0" ) {
12041234 return Error (" Array defaults are not supported yet." );
12051235 }
1236+ CheckedError err = check_enum (field, type.VectorType (), name, constant);
1237+ if (err.Check ()) {
1238+ // reset the check state of the error
1239+ return CheckedError{err};
1240+ }
12061241 } else {
12071242 if (!IsInteger (type.base_type )) {
12081243 return Error (" Enums must have integer base types" );
12091244 }
1210- // Optional and bitflags enums may have default constants that are not
1211- // their specified variants.
1212- if (!field->IsOptional () &&
1213- type.enum_def ->attributes .Lookup (" bit_flags" ) == nullptr ) {
1214- if (type.enum_def ->FindByValue (constant) == nullptr ) {
1215- return Error (" default value of `" + constant + " ` for " + " field `" +
1216- name + " ` is not part of enum `" + type.enum_def ->name +
1217- " `." );
1218- }
1245+ CheckedError err = check_enum (field, type, name, constant);
1246+ if (err.Check ()) {
1247+ // reset the check state of the error
1248+ return CheckedError{err};
12191249 }
12201250 }
12211251 }
0 commit comments