| 336 | } while (false) |
| 337 | |
| 338 | void FinalizeInputOrOutput(StringPiece spec, bool is_output, OpDef* op_def, |
| 339 | std::vector<string>* errors) { |
| 340 | OpDef::ArgDef* arg = |
| 341 | is_output ? op_def->add_output_arg() : op_def->add_input_arg(); |
| 342 | |
| 343 | StringPiece orig(spec); |
| 344 | |
| 345 | // Parse "<name>:" at the beginning. |
| 346 | StringPiece tmp_name; |
| 347 | VERIFY(ConsumeInOutName(&spec, &tmp_name), "Trouble parsing 'name:'"); |
| 348 | arg->set_name(tmp_name.data(), tmp_name.size()); |
| 349 | |
| 350 | // Detect "Ref(...)". |
| 351 | if (ConsumeInOutRefOpen(&spec)) { |
| 352 | arg->set_is_ref(true); |
| 353 | } |
| 354 | |
| 355 | { // Parse "<name|type>" or "<name>*<name|type>". |
| 356 | StringPiece first, second, type_or_attr; |
| 357 | VERIFY(ConsumeInOutNameOrType(&spec, &first), |
| 358 | "Trouble parsing either a type or an attr name at '", spec, "'"); |
| 359 | if (ConsumeInOutTimesType(&spec, &second)) { |
| 360 | arg->set_number_attr(first.data(), first.size()); |
| 361 | type_or_attr = second; |
| 362 | } else { |
| 363 | type_or_attr = first; |
| 364 | } |
| 365 | DataType dt; |
| 366 | if (DataTypeFromString(type_or_attr, &dt)) { |
| 367 | arg->set_type(dt); |
| 368 | } else { |
| 369 | const OpDef::AttrDef* attr = FindAttr(type_or_attr, *op_def); |
| 370 | VERIFY(attr != nullptr, "Reference to unknown attr '", type_or_attr, "'"); |
| 371 | if (attr->type() == "type") { |
| 372 | arg->set_type_attr(type_or_attr.data(), type_or_attr.size()); |
| 373 | } else { |
| 374 | VERIFY(attr->type() == "list(type)", "Reference to attr '", |
| 375 | type_or_attr, "' with type ", attr->type(), |
| 376 | " that isn't type or list(type)"); |
| 377 | arg->set_type_list_attr(type_or_attr.data(), type_or_attr.size()); |
| 378 | } |
| 379 | } |
| 380 | } |
| 381 | |
| 382 | // Closing ) for Ref(. |
| 383 | if (arg->is_ref()) { |
| 384 | VERIFY(ConsumeInOutRefClose(&spec), |
| 385 | "Did not find closing ')' for 'Ref(', instead found: '", spec, "'"); |
| 386 | } |
| 387 | |
| 388 | // Should not have anything else. |
| 389 | VERIFY(spec.empty(), "Extra '", spec, "' unparsed at the end"); |
| 390 | |
| 391 | // Int attrs that are the length of an input or output get a default |
| 392 | // minimum of 1. |
| 393 | if (!arg->number_attr().empty()) { |
| 394 | OpDef::AttrDef* attr = FindAttrMutable(arg->number_attr(), op_def); |
| 395 | if (attr != nullptr && !attr->has_minimum()) { |
no test coverage detected