[tint][ir] Add Decode() overload that takes a protobuf structure

Change-Id: I187790f9cb2e8914274143e79e60b328c2bbd35b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/189706
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index 780afd2..1960c60 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -50,8 +50,9 @@
 namespace {
 
 struct Decoder {
-    pb::Module& mod_in_;
-    Module& mod_out_;
+    const pb::Module& mod_in_;
+
+    Module mod_out_{};
     Vector<ir::Block*, 32> blocks_{};
     Vector<const type::Type*, 32> types_{};
     Vector<const core::constant::Value*, 32> constant_values_{};
@@ -65,7 +66,7 @@
     Vector<ir::BreakIf*, 32> break_ifs_{};
     Vector<ir::Continue*, 32> continues_{};
 
-    void Decode() {
+    Result<Module> Decode() {
         {
             const size_t n = static_cast<size_t>(mod_in_.types().size());
             types_.Reserve(n);
@@ -132,6 +133,8 @@
         for (auto* cont : continues_) {
             InferControlInstruction(cont, &Continue::SetLoop);
         }
+
+        return std::move(mod_out_);
     }
 
     template <typename EXIT, typename CTRL_INST>
@@ -1395,10 +1398,11 @@
         return Failure{"failed to deserialize protobuf"};
     }
 
-    Module mod_out;
-    Decoder{mod_in, mod_out}.Decode();
+    return Decode(mod_in);
+}
 
-    return mod_out;
+Result<Module> Decode(const pb::Module& mod_in) {
+    return Decoder{mod_in}.Decode();
 }
 
 }  // namespace tint::core::ir::binary
diff --git a/src/tint/lang/core/ir/binary/decode.h b/src/tint/lang/core/ir/binary/decode.h
index d4810b3..3e1a3ed 100644
--- a/src/tint/lang/core/ir/binary/decode.h
+++ b/src/tint/lang/core/ir/binary/decode.h
@@ -30,15 +30,22 @@
 
 #include "src/tint/utils/result/result.h"
 
-// Forward declarartion
+// Forward declarations
 namespace tint::core::ir {
 class Module;
 }  // namespace tint::core::ir
+namespace tint::core::ir::binary::pb {
+class Module;
+}  // namespace tint::core::ir::binary::pb
 
 namespace tint::core::ir::binary {
 
+/// @returns the decoded Module from the serialized protobuf.
 Result<Module> Decode(Slice<const std::byte> encoded);
 
+/// @returns the decoded Module from the protobuf.
+Result<Module> Decode(const pb::Module& module);
+
 }  // namespace tint::core::ir::binary
 
 #endif  // SRC_TINT_LANG_CORE_IR_BINARY_DECODE_H_