[dawn][emscripten] Fix Emscripten bindings for compilation messages.

- Since utf16 fields were removed from wgpu::CompilationMessage,
  we need to remove the old references, and append the extension
  in Emscripten bindings.

Bug: 400963425, 377940841
Change-Id: I882432345b980fe840d9b8f6ee22ac481fac66a3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/229334
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index f1cbdb8..5905157 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -306,12 +306,11 @@
 class StructureType(Record, Type):
     def __init__(self, is_enabled, name, json_data):
         tags = json_data.get('tags', [])
-        if 'deprecated' not in tags and 'upstream' not in tags:
-            if 'emscripten' in tags:
-                if name != 'INTERNAL_HAVE_EMDAWNWEBGPU_HEADER':
-                    assert name.startswith('emscripten'), name
-            else:
-                assert not name.startswith('emscripten'), name
+        if tags == ['emscripten']:
+            if name != 'INTERNAL_HAVE_EMDAWNWEBGPU_HEADER':
+                assert name.startswith('emscripten'), name
+        else:
+            assert not name.startswith('emscripten'), name
 
         Record.__init__(self, name)
         json_data_override = {}
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 820ddcb..33a0976 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -965,7 +965,7 @@
         "category": "structure",
         "chained": "in",
         "chain roots": ["compilation message"],
-        "tags": ["dawn"],
+        "tags": ["dawn", "emscripten"],
         "members": [
             {"name": "line pos", "type": "uint64_t"},
             {"name": "offset", "type": "uint64_t"},
@@ -3825,7 +3825,7 @@
             {"value": 61, "name": "shared fence EGL sync descriptor", "tags": ["dawn", "native"]},
             {"value": 62, "name": "shared fence EGL sync export info", "tags": ["dawn", "native"]},
             {"value": 63, "name": "dawn injected invalid s type", "tags": ["dawn"]},
-            {"value": 64, "name": "dawn compilation message utf16", "tags": ["dawn"]}
+            {"value": 64, "name": "dawn compilation message utf16", "tags": ["dawn", "emscripten"]}
         ]
     },
     "texture": {
diff --git a/src/emdawnwebgpu/tests/FuturesTests.cpp b/src/emdawnwebgpu/tests/FuturesTests.cpp
index 88be32e..aae545bd1 100644
--- a/src/emdawnwebgpu/tests/FuturesTests.cpp
+++ b/src/emdawnwebgpu/tests/FuturesTests.cpp
@@ -352,20 +352,33 @@
 
     wgpu::CompilationMessageType messageType;
     std::string message;
-    EXPECT_EQ(instance.WaitAny(shader.GetCompilationInfo(
-                                   wgpu::CallbackMode::AllowSpontaneous,
-                                   [&message, &messageType](wgpu::CompilationInfoRequestStatus s,
-                                                            const wgpu::CompilationInfo* info) {
-                                       ASSERT_EQ(s, wgpu::CompilationInfoRequestStatus::Success);
-                                       ASSERT_NE(info, nullptr);
-                                       ASSERT_EQ(info->messageCount, 1);
+    bool hasUtf16 = false;
+    EXPECT_EQ(instance.WaitAny(
+                  shader.GetCompilationInfo(
+                      wgpu::CallbackMode::AllowSpontaneous,
+                      [&message, &messageType, &hasUtf16](wgpu::CompilationInfoRequestStatus s,
+                                                          const wgpu::CompilationInfo* info) {
+                          ASSERT_EQ(s, wgpu::CompilationInfoRequestStatus::Success);
+                          ASSERT_NE(info, nullptr);
+                          ASSERT_EQ(info->messageCount, 1);
 
-                                       message = info->messages[0].message;
-                                       messageType = info->messages[0].type;
-                                   }),
-                               UINT64_MAX),
+                          message = info->messages[0].message;
+                          messageType = info->messages[0].type;
+
+                          size_t chainLength = 0;
+                          for (const auto* chain = info->messages[0].nextInChain; chain != nullptr;
+                               chain = chain->nextInChain) {
+                              if (chain->sType == wgpu::SType::DawnCompilationMessageUtf16) {
+                                  hasUtf16 = true;
+                              }
+                              chainLength++;
+                          }
+                          ASSERT_EQ(chainLength, 1);
+                      }),
+                  UINT64_MAX),
               wgpu::WaitStatus::Success);
     EXPECT_EQ(messageType, wgpu::CompilationMessageType::Warning);
+    EXPECT_TRUE(hasUtf16);
     EXPECT_THAT(message, HasSubstr("unreachable"));
 }
 
diff --git a/third_party/emdawnwebgpu/library_webgpu.js b/third_party/emdawnwebgpu/library_webgpu.js
index 6afbe56..0aa6978 100644
--- a/third_party/emdawnwebgpu/library_webgpu.js
+++ b/third_party/emdawnwebgpu/library_webgpu.js
@@ -2380,22 +2380,28 @@
 
       // Allocate and fill out each CompilationMessage.
       var compilationMessagesPtr = _malloc({{{ C_STRUCTS.WGPUCompilationMessage.__size__ }}} * compilationInfo.messages.length);
+      var utf16sPtr = _malloc({{{ C_STRUCTS.WGPUDawnCompilationMessageUtf16.__size__ }}} * compilationInfo.messages.length);
       for (var i = 0; i < compilationInfo.messages.length; ++i) {
         var compilationMessage = compilationInfo.messages[i];
         var compilationMessagePtr = compilationMessagesPtr + {{{ C_STRUCTS.WGPUCompilationMessage.__size__ }}} * i;
+        var utf16Ptr = utf16sPtr + {{{ C_STRUCTS.WGPUDawnCompilationMessageUtf16.__size__ }}} * i;
 
         // Write out the values to the CompilationMessage.
         WebGPU.setStringView(compilationMessagePtr + {{{ C_STRUCTS.WGPUCompilationMessage.message }}}, messagesPtr, messageLengths[i]);
+        // TODO: Convert JavaScript's UTF-16-code-unit offsets to UTF-8-code-unit offsets.
+        // https://github.com/webgpu-native/webgpu-headers/issues/246
+        {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.nextInChain, 'utf16Ptr', '*') }}};
         {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.type, 'WebGPU.Int_CompilationMessageType[compilationMessage.type]', 'i32') }}};
         {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.lineNum, 'compilationMessage.lineNum', 'i64') }}};
         {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.linePos, 'compilationMessage.linePos', 'i64') }}};
         {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.offset, 'compilationMessage.offset', 'i64') }}};
         {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.length, 'compilationMessage.length', 'i64') }}};
-        // TODO: Convert JavaScript's UTF-16-code-unit offsets to UTF-8-code-unit offsets.
-        // https://github.com/webgpu-native/webgpu-headers/issues/246
-        {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.utf16LinePos, 'compilationMessage.linePos', 'i64') }}};
-        {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.utf16Offset, 'compilationMessage.offset', 'i64') }}};
-        {{{ makeSetValue('compilationMessagePtr', C_STRUCTS.WGPUCompilationMessage.utf16Length, 'compilationMessage.length', 'i64') }}};
+
+        {{{ makeSetValue('utf16Ptr', C_STRUCTS.WGPUChainedStruct.next, '0', '*') }}};
+        {{{ makeSetValue('utf16Ptr', C_STRUCTS.WGPUChainedStruct.sType, gpu.SType.DawnCompilationMessageUtf16, 'i32') }}};
+        {{{ makeSetValue('utf16Ptr', C_STRUCTS.WGPUDawnCompilationMessageUtf16.linePos, 'compilationMessage.linePos', 'i64') }}};
+        {{{ makeSetValue('utf16Ptr', C_STRUCTS.WGPUDawnCompilationMessageUtf16.offset, 'compilationMessage.offset', 'i64') }}};
+        {{{ makeSetValue('utf16Ptr', C_STRUCTS.WGPUDawnCompilationMessageUtf16.length, 'compilationMessage.length', 'i64') }}};
 
         // Write the string out to the allocated buffer. Note we have to add 1
         // to the length of the string to ensure enough space for the null
diff --git a/third_party/emdawnwebgpu/webgpu.cpp b/third_party/emdawnwebgpu/webgpu.cpp
index f1bd09e..23f0a80 100644
--- a/third_party/emdawnwebgpu/webgpu.cpp
+++ b/third_party/emdawnwebgpu/webgpu.cpp
@@ -793,6 +793,8 @@
         free(const_cast<char*>(compilationInfo->messages[0].message.data));
       }
       if (compilationInfo->messages) {
+        free(reinterpret_cast<WGPUDawnCompilationMessageUtf16*>(
+            compilationInfo->messages[0].nextInChain));
         free(const_cast<WGPUCompilationMessage*>(compilationInfo->messages));
       }
       delete compilationInfo;