[dawn][wire] Make sure to copy chained structs in CompilationMessage.

- Adds chained struct handling loop to copy over Utf18 structs in
  compilation message.
- Updates tests to verify that we are doing a copy of the results
  from the server instead of directly using any memory addresses.

Bug: 480195317
Change-Id: If767970f1735d5000c51a97f55d1b68be1135281
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/288576
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
index c547cf1..8ff77a5 100644
--- a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
@@ -108,6 +108,13 @@
                                      const auto* utf16 =
                                          reinterpret_cast<const wgpu::DawnCompilationMessageUtf16*>(
                                              infoMessage->nextInChain);
+
+                                     // The client should always be copying the data returned from
+                                     // the server so the memory addresses should never be equal.
+                                     EXPECT_NE(info, &mCompilationInfo);
+                                     EXPECT_NE(infoMessage, &mMessage);
+                                     EXPECT_NE(utf16, &mUtf18);
+
                                      return infoMessage->message == mMessage.message &&
                                             infoMessage->type == mMessage.type &&
                                             infoMessage->lineNum == mMessage.lineNum &&
diff --git a/src/dawn/wire/client/ShaderModule.cpp b/src/dawn/wire/client/ShaderModule.cpp
index 252969f..08025f0 100644
--- a/src/dawn/wire/client/ShaderModule.cpp
+++ b/src/dawn/wire/client/ShaderModule.cpp
@@ -72,11 +72,40 @@
         // Deep copy the WGPUCompilationInfo
         mShader->mMessageStrings.reserve(info->messageCount);
         mShader->mMessages.reserve(info->messageCount);
+        mShader->mUtf16s.reserve(info->messageCount);
         for (size_t i = 0; i < info->messageCount; i++) {
             DAWN_ASSERT(info->messages[i].length != WGPU_STRLEN);
             mShader->mMessageStrings.push_back(ToString(info->messages[i].message));
             mShader->mMessages.push_back(info->messages[i]);
             mShader->mMessages[i].message = ToOutputStringView(mShader->mMessageStrings[i]);
+            mShader->mMessages[i].nextInChain = nullptr;
+
+            // Iterate the message chain for extensions that we want to handle.
+            WGPUChainedStruct** tail = &mShader->mMessages[i].nextInChain;
+            WGPUChainedStruct* chain = info->messages[i].nextInChain;
+            while (chain != nullptr) {
+                switch (chain->sType) {
+                    case WGPUSType_DawnCompilationMessageUtf16: {
+                        mShader->mUtf16s.push_back(
+                            *reinterpret_cast<const WGPUDawnCompilationMessageUtf16*>(chain));
+                        *tail = &mShader->mUtf16s[i].chain;
+                        break;
+                    }
+                    default:
+                        break;
+                }
+
+                // Update the tail if we added one, and go to the next chain.
+                if (*tail) {
+                    tail = &(*tail)->next;
+                }
+                chain = chain->next;
+            }
+
+            // Ensure that the tail is pointing to nothing else.
+            if (*tail) {
+                **tail = {nullptr, WGPUSType(0)};
+            }
         }
         mShader->mCompilationInfo = {nullptr, mShader->mMessages.size(), mShader->mMessages.data()};
 
diff --git a/src/dawn/wire/client/ShaderModule.h b/src/dawn/wire/client/ShaderModule.h
index 1c9da04..6d3f17c 100644
--- a/src/dawn/wire/client/ShaderModule.h
+++ b/src/dawn/wire/client/ShaderModule.h
@@ -53,6 +53,7 @@
     std::optional<WGPUCompilationInfo> mCompilationInfo;
     std::vector<std::string> mMessageStrings;
     std::vector<WGPUCompilationMessage> mMessages;
+    std::vector<WGPUDawnCompilationMessageUtf16> mUtf16s;
 };
 
 }  // namespace dawn::wire::client