Dawn: Extend and make ShaderModuleParseResult serializable

This CL combines the reflection EntryPointMetadataTable and
OwnedCompilationMessages into ShaderModuleParseResult and make it
serializable, which which enables implementing blob cache for it.

This CL also refactor DeviceBase::CreateShaderModule to prevent passing
OwnedCompilationMessages all around.

Bug: 42240459, 402772740
Change-Id: Ibabceba835df04a55285b7a6004408dfd556f999
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/244115
Auto-Submit: Zhaoming Jiang <zhaoming.jiang@microsoft.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@microsoft.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 8baef75..37939a2 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -453,7 +453,7 @@
         descriptor.nextInChain = &wgslDesc;
 
         DAWN_TRY_ASSIGN(mInternalPipelineStore->placeholderFragmentShader,
-                        CreateShaderModule(&descriptor));
+                        CreateShaderModule(&descriptor, /* internalExtensions */ {}));
     }
 
     if (HasFeature(Feature::ImplicitDeviceSynchronization)) {
@@ -1413,33 +1413,31 @@
     utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
     TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateShaderModule", "label", label.label);
 
-    ParsedCompilationMessages compilationMessages;
-    auto resultOrError =
-        CreateShaderModule(descriptor, /*internalExtensions=*/{}, &compilationMessages);
+    // parseResult is modified by CreateShaderModule via pointer to provide compilation messages in
+    // error cases.
+    ShaderModuleParseResult parseResult;
+    auto creationResult = CreateShaderModule(descriptor, /*internalExtensions=*/{}, &parseResult);
 
-    if (resultOrError.IsSuccess()) {
-        Ref<ShaderModuleBase> result = resultOrError.AcquireSuccess();
-        EmitCompilationLog(result.Get());
-        return ReturnToAPI(std::move(result));
+    if (creationResult.IsSuccess()) {
+        Ref<ShaderModuleBase> validShaderModule = creationResult.AcquireSuccess();
+        DAWN_ASSERT(validShaderModule != nullptr && !validShaderModule->IsError());
+        EmitCompilationLog(validShaderModule.Get());
+        return ReturnToAPI(std::move(validShaderModule));
     }
 
-    // Shader creation failed, acquire the device lock for error handling, and return an invalid
-    // shader module.
+    // If shader creation failed, create an error shader module with compilation messages so the
+    // application can later retrieve it with GetCompilationInfo.
+    Ref<ShaderModuleBase> errorShaderModule = ShaderModuleBase::MakeError(
+        this, descriptor ? descriptor->label : nullptr, std::move(parseResult.compilationMessages));
+    DAWN_ASSERT(errorShaderModule != nullptr && errorShaderModule->IsError());
+
+    // Acquire the device lock for error handling, and return the error shader module.
     auto deviceLock(GetScopedLock());
-    Ref<ShaderModuleBase> result;
     // Emit error, including Tint errors and warnings for the error shader module.
-    auto consumedError =
-        ConsumedError(std::move(resultOrError), &result, InternalErrorType::Internal,
-                      "calling %s.CreateShaderModule(%s).", this, descriptor);
+    auto consumedError = ConsumedError(creationResult.AcquireError(), InternalErrorType::Internal,
+                                       "calling %s.CreateShaderModule(%s).", this, descriptor);
     DAWN_ASSERT(consumedError);
-    DAWN_ASSERT(result == nullptr);
-    // The compilation messages should still be hold valid if shader module creation failed.
-    // Move the compilation messages to the error shader module so the application can later
-    // retrieve it with GetCompilationInfo.
-    result = ShaderModuleBase::MakeError(
-        this, descriptor ? descriptor->label : nullptr,
-        std::make_unique<OwnedCompilationMessages>(std::move(compilationMessages)));
-    return ReturnToAPI(std::move(result));
+    return ReturnToAPI(std::move(errorShaderModule));
 }
 
 ShaderModuleBase* DeviceBase::APICreateErrorShaderModule(const ShaderModuleDescriptor* descriptor,
@@ -1447,8 +1445,7 @@
     ParsedCompilationMessages compilationMessages;
     compilationMessages.AddUnanchoredMessage(errorMessage, wgpu::CompilationMessageType::Error);
     Ref<ShaderModuleBase> result = ShaderModuleBase::MakeError(
-        this, descriptor ? descriptor->label : nullptr,
-        std::make_unique<OwnedCompilationMessages>(std::move(compilationMessages)));
+        this, descriptor ? descriptor->label : nullptr, std::move(compilationMessages));
     auto log = result->GetCompilationLog();
 
     std::unique_ptr<ErrorData> errorData = DAWN_VALIDATION_ERROR(
@@ -2117,17 +2114,27 @@
 ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModule(
     const ShaderModuleDescriptor* descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ParsedCompilationMessages* compilationMessages) {
+    ShaderModuleParseResult* outputParseResult) {
+    // ShaderModuleParseResult holds OwnedCompilationMessages, which would be used for creating
+    // error shader module if errors occurred. If the outputParseResult is not provided, create an
+    // inplace one.
+    std::optional<ShaderModuleParseResult> inplaceParseResult;
+    if (outputParseResult == nullptr) {
+        inplaceParseResult.emplace();
+        outputParseResult = &*inplaceParseResult;
+    }
+
     DAWN_TRY(ValidateIsAlive());
 
-    // Unpack and validate the descriptor chain before doing further validation or cache lookups.
+    // Unpack and validate the descriptor chain before doing further validation or cache
+    // lookups.
     UnpackedPtr<ShaderModuleDescriptor> unpacked;
     DAWN_TRY_ASSIGN_CONTEXT(unpacked, ValidateAndUnpack(descriptor), "validating and unpacking %s",
                             descriptor);
 
+    // A WGSL (xor SPIR-V, if enabled) subdescriptor is required, and a Dawn-specific SPIR-V
+    // options descriptor is allowed when using SPIR-V.
     wgpu::SType moduleType = wgpu::SType(0u);
-    // A WGSL (or SPIR-V, if enabled) subdescriptor is required, and a Dawn-specific SPIR-V options
-    // descriptor is allowed when using SPIR-V.
     DAWN_TRY_ASSIGN(
         moduleType,
         (unpacked.ValidateBranches<Branch<ShaderSourceWGSL, ShaderModuleCompilationOptions>,
@@ -2159,35 +2166,21 @@
     const size_t blueprintHash = blueprint.ComputeContentHash();
     blueprint.SetContentHash(blueprintHash);
 
+    // Check in-memory shader module cache first, and if missed call ParseShaderModule.
     return GetOrCreate(
         mCaches->shaderModules, &blueprint, [&]() -> ResultOrError<Ref<ShaderModuleBase>> {
-            // If the compilationMessages is nullptr, caller of this function assumes that the
-            // shader creation will succeed and doesn't care the compilation messages. However we
-            // still use a inplace compile messages to ensure every shader module in the cache have
-            // a valid OwnedCompilationMessages.
-            ParsedCompilationMessages inplaceCompilationMessages;
-            if (compilationMessages == nullptr) {
-                compilationMessages = &inplaceCompilationMessages;
-            }
-
             SCOPED_DAWN_HISTOGRAM_TIMER_MICROS(GetPlatform(), "CreateShaderModuleUS");
 
             auto resultOrError = [&]() -> ResultOrError<Ref<ShaderModuleBase>> {
-                // Shader parsing and validating are always delayed until cache missed.
-                ShaderModuleParseResult parseResult;
                 // Try to validate and parse the shader code, and if an error occurred return it
                 // without updating the cache.
-                DAWN_TRY(ParseShaderModule(this, unpacked, internalExtensions, &parseResult,
-                                           compilationMessages));
+                DAWN_TRY(ParseShaderModule(this, unpacked, internalExtensions,
+                                           /* needReflection */ true, outputParseResult));
 
                 Ref<ShaderModuleBase> shaderModule;
-                // If created successfully, compilation messages are moved into the shader module.
-                DAWN_ASSERT(compilationMessages);
-                auto ownedCompilationMessages =
-                    std::make_unique<OwnedCompilationMessages>(std::move(*compilationMessages));
-                DAWN_TRY_ASSIGN(shaderModule,
-                                CreateShaderModuleImpl(unpacked, internalExtensions, &parseResult,
-                                                       &ownedCompilationMessages));
+                // If created successfully, outputParseResult are moved into the shader module.
+                DAWN_TRY_ASSIGN(shaderModule, CreateShaderModuleImpl(unpacked, internalExtensions,
+                                                                     outputParseResult));
                 shaderModule->SetContentHash(blueprintHash);
                 return shaderModule;
             }();
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h
index c5bc221..6c41b55 100644
--- a/src/dawn/native/Device.h
+++ b/src/dawn/native/Device.h
@@ -216,7 +216,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModule(
         const ShaderModuleDescriptor* descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions = {},
-        ParsedCompilationMessages* compilationMessages = nullptr);
+        ShaderModuleParseResult* outputParseResult = nullptr);
     ResultOrError<Ref<SwapChainBase>> CreateSwapChain(Surface* surface,
                                                       SwapChainBase* previousSwapChain,
                                                       const SurfaceConfiguration* config);
@@ -482,8 +482,7 @@
     virtual ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) = 0;
+        ShaderModuleParseResult* parseResult) = 0;
     // Note that previousSwapChain may be nullptr, or come from a different backend.
     virtual ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index ffbd580..164d4cc 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -1294,26 +1294,22 @@
     return Extent3D{x, y, z};
 }
 
-ShaderModuleParseResult::ShaderModuleParseResult() = default;
-ShaderModuleParseResult::~ShaderModuleParseResult() = default;
-
-ShaderModuleParseResult::ShaderModuleParseResult(ShaderModuleParseResult&& rhs) = default;
-
-ShaderModuleParseResult& ShaderModuleParseResult::operator=(ShaderModuleParseResult&& rhs) =
-    default;
-
-bool ShaderModuleParseResult::HasParsedShader() const {
-    return tintProgram != nullptr;
+bool ShaderModuleParseResult::HasTintProgram() const {
+    return tintProgram.UnsafeGetValue().has_value() &&
+           tintProgram.UnsafeGetValue().value() != nullptr;
 }
 
 MaybeError ParseShaderModule(DeviceBase* device,
                              const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                              const std::vector<tint::wgsl::Extension>& internalExtensions,
-                             ShaderModuleParseResult* parseResult,
-                             ParsedCompilationMessages* outMessages) {
+                             bool needReflection,
+                             ShaderModuleParseResult* parseResult) {
     DAWN_ASSERT(parseResult != nullptr);
 
-    // We assume that the descriptor chain has already been validated.
+    ParsedCompilationMessages* outMessages = &parseResult->compilationMessages;
+
+    // Parse shader module to generate uncacheable part of parse result. Assuming the descriptor
+    // chain has already been validated.
 #if TINT_BUILD_SPV_READER
     // Handling SPIR-V if enabled.
     if (const auto* spirvDesc = descriptor.Get<ShaderSourceSPIRV>()) {
@@ -1335,9 +1331,8 @@
         tint::Program program;
         DAWN_TRY_ASSIGN(program, ParseSPIRV(spirv, device->GetWGSLAllowedFeatures(), outMessages,
                                             spirvOptions));
-        parseResult->tintProgram = AcquireRef(new TintProgram(std::move(program), nullptr));
-
-        return {};
+        parseResult->tintProgram = UnsafeUnserializedValue<std::optional<Ref<TintProgram>>>(
+            AcquireRef(new TintProgram(std::move(program), nullptr)));
     }
 #else   // TINT_BUILD_SPV_READER
     // SPIR-V is not enabled, so the descriptor should not contain it.
@@ -1345,22 +1340,32 @@
 #endif  // TINT_BUILD_SPV_READER
 
     // Handling WGSL.
-    const ShaderSourceWGSL* wgslDesc = descriptor.Get<ShaderSourceWGSL>();
-    DAWN_ASSERT(wgslDesc != nullptr);
+    if (const ShaderSourceWGSL* wgslDesc = descriptor.Get<ShaderSourceWGSL>()) {
+        auto tintFile = std::make_unique<tint::Source::File>("", wgslDesc->code);
 
-    auto tintFile = std::make_unique<tint::Source::File>("", wgslDesc->code);
+        if (device->IsToggleEnabled(Toggle::DumpShaders)) {
+            std::ostringstream dumpedMsg;
+            dumpedMsg << "// Dumped WGSL:\n" << std::string_view(wgslDesc->code) << "\n";
+            device->EmitLog(WGPULoggingType_Info, dumpedMsg.str().c_str());
+        }
 
-    if (device->IsToggleEnabled(Toggle::DumpShaders)) {
-        std::ostringstream dumpedMsg;
-        dumpedMsg << "// Dumped WGSL:\n" << std::string_view(wgslDesc->code) << "\n";
-        device->EmitLog(WGPULoggingType_Info, dumpedMsg.str().c_str());
+        tint::Program program;
+        DAWN_TRY_ASSIGN(program, ParseWGSL(tintFile.get(), device->GetWGSLAllowedFeatures(),
+                                           internalExtensions, outMessages));
+        parseResult->tintProgram = UnsafeUnserializedValue<std::optional<Ref<TintProgram>>>(
+            AcquireRef(new TintProgram(std::move(program), std::move(tintFile))));
     }
 
-    tint::Program program;
-    DAWN_TRY_ASSIGN(program, ParseWGSL(tintFile.get(), device->GetWGSLAllowedFeatures(),
-                                       internalExtensions, outMessages));
+    // Assert parsed shader are correctly generated.
+    DAWN_ASSERT(parseResult->HasTintProgram());
 
-    parseResult->tintProgram = AcquireRef(new TintProgram(std::move(program), std::move(tintFile)));
+    // Generate reflection information if required.
+    if (needReflection) {
+        parseResult->metadataTable.emplace();
+        DAWN_TRY(ReflectShaderUsingTint(device,
+                                        &parseResult->tintProgram.UnsafeGetValue().value()->program,
+                                        &parseResult->metadataTable.value()));
+    }
 
     return {};
 }
@@ -1555,10 +1560,11 @@
 ShaderModuleBase::ShaderModuleBase(DeviceBase* device,
                                    ObjectBase::ErrorTag tag,
                                    StringView label,
-                                   std::unique_ptr<OwnedCompilationMessages> compilationMessages)
+                                   ParsedCompilationMessages&& compilationMessages)
     : Base(device, tag, label),
       mType(Type::Undefined),
-      mCompilationMessages(std::move(compilationMessages)) {}
+      mCompilationMessages(
+          std::make_unique<OwnedCompilationMessages>(std::move(compilationMessages))) {}
 
 ShaderModuleBase::~ShaderModuleBase() = default;
 
@@ -1567,10 +1573,9 @@
 }
 
 // static
-Ref<ShaderModuleBase> ShaderModuleBase::MakeError(
-    DeviceBase* device,
-    StringView label,
-    std::unique_ptr<OwnedCompilationMessages> compilationMessages) {
+Ref<ShaderModuleBase> ShaderModuleBase::MakeError(DeviceBase* device,
+                                                  StringView label,
+                                                  ParsedCompilationMessages&& compilationMessages) {
     return AcquireRef(
         new ShaderModuleBase(device, ObjectBase::kError, label, std::move(compilationMessages)));
 }
@@ -1663,13 +1668,14 @@
                 DAWN_UNREACHABLE();
         }
 
-        ShaderModuleParseResult parseResult;
-        ParseShaderModule(GetDevice(), Unpack(&descriptor), mInternalExtensions, &parseResult,
-                          /*compilationMessages*/ nullptr)
+        ShaderModuleParseResult regeneratedParseResult;
+        ParseShaderModule(GetDevice(), Unpack(&descriptor), mInternalExtensions,
+                          /* needReflection */ false, &regeneratedParseResult)
             .AcquireSuccess();
-        DAWN_ASSERT(parseResult.tintProgram != nullptr);
+        DAWN_ASSERT(regeneratedParseResult.HasTintProgram());
 
-        tintData->tintProgram = std::move(parseResult.tintProgram);
+        tintData->tintProgram =
+            std::move(regeneratedParseResult.tintProgram.UnsafeGetValue().value());
         tintData->tintProgramRecreateCount++;
 
         return tintData->tintProgram;
@@ -1748,16 +1754,14 @@
     mCompilationMessages = std::move(*compilationMessages);
 }
 
-MaybeError ShaderModuleBase::InitializeBase(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    DAWN_TRY(mTintData.Use([&](auto tintData) -> MaybeError {
-        tintData->tintProgram = std::move(parseResult->tintProgram);
-
-        DAWN_TRY(
-            ReflectShaderUsingTint(GetDevice(), &(tintData->tintProgram->program), &mEntryPoints));
-        return {};
-    }));
+MaybeError ShaderModuleBase::InitializeBase(ShaderModuleParseResult* parseResult) {
+    if (parseResult->HasTintProgram()) {
+        mTintData.Use([&](auto tintData) {
+            tintData->tintProgram = std::move(parseResult->tintProgram.UnsafeGetValue().value());
+        });
+    }
+    DAWN_ASSERT(parseResult->metadataTable.has_value());
+    mEntryPoints = std::move(parseResult->metadataTable.value());
 
     for (auto stage : IterateStages(kAllStages)) {
         mEntryPointCounts[stage] = 0;
@@ -1774,7 +1778,8 @@
     // inject only once for each shader module.
     DAWN_ASSERT(mCompilationMessages == nullptr);
     // Move the compilationMessages into the shader module and emit the tint errors and warnings
-    mCompilationMessages = std::move(*compilationMessages);
+    mCompilationMessages =
+        std::make_unique<OwnedCompilationMessages>(std::move(parseResult->compilationMessages));
 
     return {};
 }
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index 6eee850..e474ea4 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -113,29 +113,32 @@
     const std::unique_ptr<tint::Source::File> file;  // Keep the tint::Source::File alive
 };
 
-struct ShaderModuleParseResult {
-    ShaderModuleParseResult();
-    ~ShaderModuleParseResult();
-    ShaderModuleParseResult(ShaderModuleParseResult&& rhs);
-    ShaderModuleParseResult& operator=(ShaderModuleParseResult&& rhs);
-
-    bool HasParsedShader() const;
-
-    Ref<TintProgram> tintProgram;
+// ShaderModuleParseResult is used for shader module creation and can be generated by
+// ParseShaderModule or loaded from blob cache.
+#define SHADER_MODULE_PARSE_RESULT_MEMBER(X)                                                  \
+    X(UnsafeUnserializedValue<std::optional<Ref<TintProgram>>>, tintProgram)                  \
+    /* EntryPointMetadataTable might be unnecessary in cases like Tint Program recreation. */ \
+    X(std::optional<EntryPointMetadataTable>, metadataTable)                                  \
+    X(ParsedCompilationMessages, compilationMessages)
+DAWN_SERIALIZABLE(struct, ShaderModuleParseResult, SHADER_MODULE_PARSE_RESULT_MEMBER) {
+    // Check if ShaderModuleParseResult holds a valid tintProgram. A ShaderModuleParseResult loaded
+    // from blob cache holds no tintProgram but other information.
+    bool HasTintProgram() const;
 };
+#undef SHADER_MODULE_PARSE_RESULT_MEMBER
 
 struct ShaderModuleEntryPoint {
     bool defaulted;
     std::string name;
 };
 
-// Parse a shader module from a validated ShaderModuleDescriptor. Errors are generated only if the
-// shader code itself is invalid.
+// Parse a shader module from a validated ShaderModuleDescriptor, and generate reflection
+// information if required. Errors are returned only if the shader code itself is invalid.
 MaybeError ParseShaderModule(DeviceBase* device,
                              const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                              const std::vector<tint::wgsl::Extension>& internalExtensions,
-                             ShaderModuleParseResult* parseResult,
-                             ParsedCompilationMessages* outMessages);
+                             bool needReflection,
+                             ShaderModuleParseResult* parseResult);
 
 MaybeError ValidateCompatibilityWithPipelineLayout(DeviceBase* device,
                                                    const EntryPointMetadata& entryPoint,
@@ -343,10 +346,9 @@
                      std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModuleBase() override;
 
-    static Ref<ShaderModuleBase> MakeError(
-        DeviceBase* device,
-        StringView label,
-        std::unique_ptr<OwnedCompilationMessages> compilationMessages);
+    static Ref<ShaderModuleBase> MakeError(DeviceBase* device,
+                                           StringView label,
+                                           ParsedCompilationMessages&& compilationMessages);
 
     ObjectType GetType() const override;
 
@@ -398,14 +400,13 @@
   protected:
     void DestroyImpl() override;
 
-    MaybeError InitializeBase(ShaderModuleParseResult* parseResult,
-                              std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError InitializeBase(ShaderModuleParseResult* parseResult);
 
   private:
     ShaderModuleBase(DeviceBase* device,
                      ObjectBase::ErrorTag tag,
                      StringView label,
-                     std::unique_ptr<OwnedCompilationMessages> compilationMessages);
+                     ParsedCompilationMessages&& compilationMessages);
 
     void WillDropLastExternalRef() override;
 
diff --git a/src/dawn/native/d3d11/DeviceD3D11.cpp b/src/dawn/native/d3d11/DeviceD3D11.cpp
index 2a8c7e7..b8e74e5 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.cpp
+++ b/src/dawn/native/d3d11/DeviceD3D11.cpp
@@ -287,10 +287,8 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult,
-                                compilationMessages);
+    ShaderModuleParseResult* parseResult) {
+    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult);
 }
 
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
diff --git a/src/dawn/native/d3d11/DeviceD3D11.h b/src/dawn/native/d3d11/DeviceD3D11.h
index a56d38e..e66cc97 100644
--- a/src/dawn/native/d3d11/DeviceD3D11.h
+++ b/src/dawn/native/d3d11/DeviceD3D11.h
@@ -119,8 +119,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
index c8ff479..d22d324 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -58,10 +58,9 @@
     Device* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 
@@ -70,10 +69,8 @@
                            std::vector<tint::wgsl::Extension> internalExtensions)
     : ShaderModuleBase(device, descriptor, std::move(internalExtensions)) {}
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return InitializeBase(parseResult, compilationMessages);
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    return InitializeBase(parseResult);
 }
 
 ResultOrError<d3d::CompiledShader> ShaderModule::Compile(
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.h b/src/dawn/native/d3d11/ShaderModuleD3D11.h
index eb0d88f..476099d 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.h
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.h
@@ -54,8 +54,7 @@
         Device* device,
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+        ShaderModuleParseResult* parseResult);
 
     ResultOrError<d3d::CompiledShader> Compile(
         const ProgrammableStage& programmableStage,
@@ -72,8 +71,7 @@
                  const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                  std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModule() override = default;
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
 };
 
 }  // namespace dawn::native::d3d11
diff --git a/src/dawn/native/d3d12/DeviceD3D12.cpp b/src/dawn/native/d3d12/DeviceD3D12.cpp
index 6907fe7..320a49e 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/DeviceD3D12.cpp
@@ -395,10 +395,8 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult,
-                                compilationMessages);
+    ShaderModuleParseResult* parseResult) {
+    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult);
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
                                                               SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/d3d12/DeviceD3D12.h b/src/dawn/native/d3d12/DeviceD3D12.h
index d672711..9a4d7f3 100644
--- a/src/dawn/native/d3d12/DeviceD3D12.h
+++ b/src/dawn/native/d3d12/DeviceD3D12.h
@@ -194,8 +194,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index d4bf39e..a49c6a8 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -101,10 +101,9 @@
     Device* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 
@@ -113,10 +112,8 @@
                            std::vector<tint::wgsl::Extension> internalExtensions)
     : ShaderModuleBase(device, descriptor, std::move(internalExtensions)) {}
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return InitializeBase(parseResult, compilationMessages);
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    return InitializeBase(parseResult);
 }
 
 ResultOrError<d3d::CompiledShader> ShaderModule::Compile(
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.h b/src/dawn/native/d3d12/ShaderModuleD3D12.h
index aefebd9..0dfe05e 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.h
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.h
@@ -54,8 +54,7 @@
         Device* device,
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+        ShaderModuleParseResult* parseResult);
 
     ResultOrError<d3d::CompiledShader> Compile(
         const ProgrammableStage& programmableStage,
@@ -70,8 +69,7 @@
                  const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                  std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModule() override = default;
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
 };
 
 }  // namespace dawn::native::d3d12
diff --git a/src/dawn/native/metal/DeviceMTL.h b/src/dawn/native/metal/DeviceMTL.h
index 5c1b377..ba85a5f 100644
--- a/src/dawn/native/metal/DeviceMTL.h
+++ b/src/dawn/native/metal/DeviceMTL.h
@@ -113,8 +113,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/metal/DeviceMTL.mm b/src/dawn/native/metal/DeviceMTL.mm
index 6664816..4d259c8 100644
--- a/src/dawn/native/metal/DeviceMTL.mm
+++ b/src/dawn/native/metal/DeviceMTL.mm
@@ -228,10 +228,8 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult,
-                                compilationMessages);
+    ShaderModuleParseResult* parseResult) {
+    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult);
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
                                                               SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/metal/ShaderModuleMTL.h b/src/dawn/native/metal/ShaderModuleMTL.h
index 61f5c18..6db6620 100644
--- a/src/dawn/native/metal/ShaderModuleMTL.h
+++ b/src/dawn/native/metal/ShaderModuleMTL.h
@@ -55,8 +55,7 @@
         Device* device,
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+        ShaderModuleParseResult* parseResult);
 
     struct MetalFunctionData {
         NSPRef<id<MTLFunction>> function;
@@ -77,8 +76,7 @@
                  const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                  std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModule() override;
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
 };
 
 }  // namespace dawn::native::metal
diff --git a/src/dawn/native/metal/ShaderModuleMTL.mm b/src/dawn/native/metal/ShaderModuleMTL.mm
index d487537..e930b7f 100644
--- a/src/dawn/native/metal/ShaderModuleMTL.mm
+++ b/src/dawn/native/metal/ShaderModuleMTL.mm
@@ -105,10 +105,9 @@
     Device* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 
@@ -119,10 +118,8 @@
 
 ShaderModule::~ShaderModule() = default;
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return InitializeBase(parseResult, compilationMessages);
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    return InitializeBase(parseResult);
 }
 
 namespace {
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index 4baddba..08bbc35 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -236,10 +236,9 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(this, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
@@ -576,10 +575,8 @@
 
 // ShaderModule
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return InitializeBase(parseResult, compilationMessages);
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    return InitializeBase(parseResult);
 }
 
 uint32_t Device::GetOptimalBytesPerRowAlignment() const {
diff --git a/src/dawn/native/null/DeviceNull.h b/src/dawn/native/null/DeviceNull.h
index f28221a..6c5f623 100644
--- a/src/dawn/native/null/DeviceNull.h
+++ b/src/dawn/native/null/DeviceNull.h
@@ -161,8 +161,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
@@ -323,8 +322,7 @@
   public:
     using ShaderModuleBase::ShaderModuleBase;
 
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
 };
 
 class SwapChain final : public SwapChainBase {
diff --git a/src/dawn/native/opengl/DeviceGL.cpp b/src/dawn/native/opengl/DeviceGL.cpp
index 86ddb842..063c513 100644
--- a/src/dawn/native/opengl/DeviceGL.cpp
+++ b/src/dawn/native/opengl/DeviceGL.cpp
@@ -282,10 +282,8 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult,
-                                compilationMessages);
+    ShaderModuleParseResult* parseResult) {
+    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult);
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
                                                               SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/opengl/DeviceGL.h b/src/dawn/native/opengl/DeviceGL.h
index 71713d5..1f03412 100644
--- a/src/dawn/native/opengl/DeviceGL.h
+++ b/src/dawn/native/opengl/DeviceGL.h
@@ -132,8 +132,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/opengl/ShaderModuleGL.cpp b/src/dawn/native/opengl/ShaderModuleGL.cpp
index 41109c7..7446b6d 100644
--- a/src/dawn/native/opengl/ShaderModuleGL.cpp
+++ b/src/dawn/native/opengl/ShaderModuleGL.cpp
@@ -348,10 +348,9 @@
     Device* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 
@@ -360,10 +359,8 @@
                            std::vector<tint::wgsl::Extension> internalExtensions)
     : ShaderModuleBase(device, descriptor, std::move(internalExtensions)) {}
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    DAWN_TRY(InitializeBase(parseResult, compilationMessages));
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    DAWN_TRY(InitializeBase(parseResult));
 
     return {};
 }
diff --git a/src/dawn/native/opengl/ShaderModuleGL.h b/src/dawn/native/opengl/ShaderModuleGL.h
index 4327435..1770f71 100644
--- a/src/dawn/native/opengl/ShaderModuleGL.h
+++ b/src/dawn/native/opengl/ShaderModuleGL.h
@@ -86,8 +86,7 @@
         Device* device,
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+        ShaderModuleParseResult* parseResult);
 
     ResultOrError<GLuint> CompileShader(const OpenGLFunctions& gl,
                                         const ProgrammableStage& programmableStage,
@@ -107,8 +106,7 @@
                  const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                  std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModule() override = default;
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
 };
 
 }  // namespace opengl
diff --git a/src/dawn/native/utils/WGPUHelpers.cpp b/src/dawn/native/utils/WGPUHelpers.cpp
index 8d1ea7b..4592036 100644
--- a/src/dawn/native/utils/WGPUHelpers.cpp
+++ b/src/dawn/native/utils/WGPUHelpers.cpp
@@ -56,8 +56,7 @@
     wgslDesc.code = source;
     ShaderModuleDescriptor descriptor;
     descriptor.nextInChain = &wgslDesc;
-    ParsedCompilationMessages compilationMessages;
-    return device->CreateShaderModule(&descriptor, internalExtensions, &compilationMessages);
+    return device->CreateShaderModule(&descriptor, internalExtensions);
 }
 
 ResultOrError<Ref<BufferBase>> CreateBufferFromData(DeviceBase* device,
diff --git a/src/dawn/native/vulkan/DeviceVk.cpp b/src/dawn/native/vulkan/DeviceVk.cpp
index 58d41f8..78b321b 100644
--- a/src/dawn/native/vulkan/DeviceVk.cpp
+++ b/src/dawn/native/vulkan/DeviceVk.cpp
@@ -233,10 +233,8 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult,
-                                compilationMessages);
+    ShaderModuleParseResult* parseResult) {
+    return ShaderModule::Create(this, descriptor, internalExtensions, parseResult);
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
                                                               SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/vulkan/DeviceVk.h b/src/dawn/native/vulkan/DeviceVk.h
index 2b5a60b..65df853 100644
--- a/src/dawn/native/vulkan/DeviceVk.h
+++ b/src/dawn/native/vulkan/DeviceVk.h
@@ -155,8 +155,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.cpp b/src/dawn/native/vulkan/ShaderModuleVk.cpp
index 45a2f08..da62f09 100644
--- a/src/dawn/native/vulkan/ShaderModuleVk.cpp
+++ b/src/dawn/native/vulkan/ShaderModuleVk.cpp
@@ -88,10 +88,9 @@
     Device* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor, internalExtensions));
-    DAWN_TRY(module->Initialize(parseResult, compilationMessages));
+    DAWN_TRY(module->Initialize(parseResult));
     return module;
 }
 
@@ -100,10 +99,8 @@
                            std::vector<tint::wgsl::Extension> internalExtensions)
     : ShaderModuleBase(device, descriptor, std::move(internalExtensions)) {}
 
-MaybeError ShaderModule::Initialize(
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
-    return InitializeBase(parseResult, compilationMessages);
+MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
+    return InitializeBase(parseResult);
 }
 
 void ShaderModule::DestroyImpl() {
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.h b/src/dawn/native/vulkan/ShaderModuleVk.h
index 8e9b451..b9bf6d7 100644
--- a/src/dawn/native/vulkan/ShaderModuleVk.h
+++ b/src/dawn/native/vulkan/ShaderModuleVk.h
@@ -62,8 +62,7 @@
         Device* device,
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+        ShaderModuleParseResult* parseResult);
 
     // Caller is responsible for destroying the `VkShaderModule` returned.
     ResultOrError<ModuleAndSpirv> GetHandleAndSpirv(SingleShaderStage stage,
@@ -77,8 +76,7 @@
                  const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
                  std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModule() override;
-    MaybeError Initialize(ShaderModuleParseResult* parseResult,
-                          std::unique_ptr<OwnedCompilationMessages>* compilationMessages);
+    MaybeError Initialize(ShaderModuleParseResult* parseResult);
     void DestroyImpl() override;
 };
 
diff --git a/src/dawn/native/webgpu/DeviceWGPU.cpp b/src/dawn/native/webgpu/DeviceWGPU.cpp
index aceb775..6fe43f4 100644
--- a/src/dawn/native/webgpu/DeviceWGPU.cpp
+++ b/src/dawn/native/webgpu/DeviceWGPU.cpp
@@ -174,8 +174,7 @@
 ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
     const std::vector<tint::wgsl::Extension>& internalExtensions,
-    ShaderModuleParseResult* parseResult,
-    std::unique_ptr<OwnedCompilationMessages>* compilationMessages) {
+    ShaderModuleParseResult* parseResult) {
     return Ref<ShaderModuleBase>{nullptr};
 }
 ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
diff --git a/src/dawn/native/webgpu/DeviceWGPU.h b/src/dawn/native/webgpu/DeviceWGPU.h
index 714ebdd..bb8c3fd 100644
--- a/src/dawn/native/webgpu/DeviceWGPU.h
+++ b/src/dawn/native/webgpu/DeviceWGPU.h
@@ -88,8 +88,7 @@
     ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
         const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
         const std::vector<tint::wgsl::Extension>& internalExtensions,
-        ShaderModuleParseResult* parseResult,
-        std::unique_ptr<OwnedCompilationMessages>* compilationMessages) override;
+        ShaderModuleParseResult* parseResult) override;
     ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
         Surface* surface,
         SwapChainBase* previousSwapChain,
diff --git a/src/dawn/tests/unittests/native/mocks/DeviceMock.h b/src/dawn/tests/unittests/native/mocks/DeviceMock.h
index 27bc5ae..a0689d6 100644
--- a/src/dawn/tests/unittests/native/mocks/DeviceMock.h
+++ b/src/dawn/tests/unittests/native/mocks/DeviceMock.h
@@ -118,8 +118,7 @@
                 CreateShaderModuleImpl,
                 (const UnpackedPtr<ShaderModuleDescriptor>&,
                  const std::vector<tint::wgsl::Extension>&,
-                 ShaderModuleParseResult*,
-                 std::unique_ptr<OwnedCompilationMessages>*),
+                 ShaderModuleParseResult*),
                 (override));
     MOCK_METHOD(ResultOrError<Ref<SwapChainBase>>,
                 CreateSwapChainImpl,
diff --git a/src/dawn/tests/unittests/native/mocks/ShaderModuleMock.cpp b/src/dawn/tests/unittests/native/mocks/ShaderModuleMock.cpp
index 6a1659c..748218e 100644
--- a/src/dawn/tests/unittests/native/mocks/ShaderModuleMock.cpp
+++ b/src/dawn/tests/unittests/native/mocks/ShaderModuleMock.cpp
@@ -50,15 +50,13 @@
 Ref<ShaderModuleMock> ShaderModuleMock::Create(
     DeviceMock* device,
     const UnpackedPtr<ShaderModuleDescriptor>& descriptor) {
-    ShaderModuleParseResult parseResult;
-    ParsedCompilationMessages compilationMessages;
-    ParseShaderModule(device, descriptor, {}, &parseResult, &compilationMessages).AcquireSuccess();
-    auto ownedCompilationMessages =
-        std::make_unique<OwnedCompilationMessages>(std::move(compilationMessages));
+    ShaderModuleParseResult parseResult{};
+    ParseShaderModule(device, descriptor, {}, /* needReflection*/ true, &parseResult)
+        .AcquireSuccess();
 
     Ref<ShaderModuleMock> shaderModule =
         AcquireRef(new NiceMock<ShaderModuleMock>(device, descriptor));
-    shaderModule->InitializeBase(&parseResult, &ownedCompilationMessages).AcquireSuccess();
+    shaderModule->InitializeBase(&parseResult).AcquireSuccess();
     return shaderModule;
 }