Refactor the asmparser hook to work with a new OperationState type that fully
encapsulates an operation that is yet to be created.  This is a patch towards
custom ops providing create methods that don't need to be templated, allowing
them to move out of line in the future.

PiperOrigin-RevId: 207725557
diff --git a/lib/IR/Builders.cpp b/lib/IR/Builders.cpp
index 715e460..4424bd3 100644
--- a/lib/IR/Builders.cpp
+++ b/lib/IR/Builders.cpp
@@ -158,10 +158,36 @@
   return b;
 }
 
+/// Create an operation given the fields represented as an OperationState.
+OperationInst *CFGFuncBuilder::createOperation(const OperationState &state) {
+  SmallVector<CFGValue *, 8> operands;
+  operands.reserve(state.operands.size());
+  for (auto elt : state.operands)
+    operands.push_back(cast<CFGValue>(elt));
+
+  auto *op = OperationInst::create(state.name, operands, state.types,
+                                   state.attributes, context);
+  block->getOperations().insert(insertPoint, op);
+  return op;
+}
+
 //===----------------------------------------------------------------------===//
 // Statements.
 //===----------------------------------------------------------------------===//
 
+/// Create an operation given the fields represented as an OperationState.
+OperationStmt *MLFuncBuilder::createOperation(const OperationState &state) {
+  SmallVector<MLValue *, 8> operands;
+  operands.reserve(state.operands.size());
+  for (auto elt : state.operands)
+    operands.push_back(cast<MLValue>(elt));
+
+  auto *op = OperationStmt::create(state.name, operands, state.types,
+                                   state.attributes, context);
+  block->getStatements().insert(insertPoint, op);
+  return op;
+}
+
 ForStmt *MLFuncBuilder::createFor(AffineConstantExpr *lowerBound,
                                   AffineConstantExpr *upperBound,
                                   AffineConstantExpr *step) {