Vào sáng ngày 21 tháng 9, trong kho lưu trữ libprisma — thư viện Telegram dùng để tô màu khối mã trong tin nhắn — đã có 12 thay đổi chỉ trong vòng 3 giờ. Bảng ngôn ngữ đã được cập nhật thêm Tolk, ngôn ngữ chính cho hợp đồng thông minh TON, đồng thời cập nhật định nghĩa cho Tact và FunC, và lần đầu tiên kể từ ngày 20 tháng 11 năm 2023, file chính đã được xây dựng lại.

Hiện tại, người dùng vẫn chưa thấy thay đổi nào trong ứng dụng. Mỗi client đều mang theo bản sao riêng của bảng ngôn ngữ, và cả ba bản sao này đều được lấy từ năm 2023.

Một hợp đồng giống nhau trên Tolk, bên trái là văn bản chữ thường màu xám, bên phải là tô màu sắc
Bên trái — khối mã với nhãn `tolk` như cách các client hiện tại hiển thị. Bên phải — cùng khối mã, được phân tích theo định nghĩa ngôn ngữ chuẩn. Ví dụ hợp đồng được lấy từ bài giới thiệu Tolk trong tài liệu TON.

Cách Telegram tô màu mã nguồn

Khối mã trong tin nhắn được phân tích không phải bởi máy chủ, mà bởi chính ứng dụng client. Trách nhiệm này thuộc về libprisma — bản chuyển đổi từ thư viện Prism.js dành cho trình duyệt sang C++, được Telegram công bố vào mùa thu năm 2023. Các quy tắc ngôn ngữ được tạo từ hai nguồn: gói Prism.js và một số file được viết trực tiếp trong kho lưu trữ, trong đó chứa các ngôn ngữ TON. Sau khi được chuẩn hóa, chúng được gộp thành một file nhị phân duy nhất grammars.dat. Client sẽ tải file này khi khởi động, rồi hỏi nó để xác định từng token trong khối mã — từ từ khóa, chuỗi, đến chú thích.

File này chính là toàn bộ danh sách ngôn ngữ được hỗ trợ. Nếu ngôn ngữ không có trong bảng, khối mã sẽ vẫn hiển thị dưới dạng văn bản đơn sắc, dù người viết có ghi rõ tolk sau ba dấu nháy ngược.

Android hoạt động khác biệt: động cơ Prism ở đây được viết lại bằng Java, và bảng ngôn ngữ nằm riêng biệt dưới dạng codelng.gzip, được đưa vào từ phiên bản 10.2 vào cuối tháng 10 năm 2023. Lịch sử. Do sử dụng các động cơ biểu thức chính quy khác nhau — Boost trong C++ và java.util.regex trong Java — nên số lượng thay đổi lần này lên tới 12, chứ không chỉ 2 như dự kiến.

Tại sao các ngôn ngữ TON vẫn còn màu xám

Chúng vẫn màu xám không phải vì chưa có quy tắc cho TON. Bốn ngôn ngữ — Tact, FunC, Fift và TL-B — đã được đưa vào mã nguồn libprisma vào tháng 5 năm 2024. Bốn tháng sau, một bản cập nhật khác được gửi vào tháng 9 năm 2024: nâng cấp Tact từ phiên bản 1.2.0 lên 1.6.0, và viết lại hoàn toàn FunC từ 0.2.0 lên 0.4.4.

Tuy nhiên, cả hai thay đổi này đều chưa đến được ứng dụng, và nguyên nhân không nằm ở ứng dụng. Các quy tắc ngôn ngữ được lưu như file thông thường trong kho, nhưng client chỉ đọc bảng nhị phân được xây dựng từ chúng — và lần cuối cùng bảng này được xây dựng là ngày 20 tháng 11 năm 2023, tức là nửa năm trước khi ngôn ngữ TON đầu tiên xuất hiện trong kho. Mọi thay đổi sau đó chỉ tồn tại trong mã nguồn, chưa bao giờ được gửi đi.

Quy trình xây dựng được thực hiện qua GitHub Actions, nhưng công cụ này đã bị ngừng hoạt động: actions/upload-artifact@v3 bị loại bỏ khỏi sử dụng, khiến nhiệm vụ bị lỗi ngay từ đầu. Cập nhật Tact và FunC vì thế đã bị treo suốt hai năm.

Tolk là một trường hợp riêng. Ngôn ngữ này ra đời như một bước phát triển từ FunC, và hiện nay trong tài liệu TON được khuyến nghị sử dụng, trong khi FunC đã được chuyển sang trạng thái lỗi thời. Trong libprisma, Tolk được đề xuất vào tháng 5 năm 2026, nhưng vẫn giữ ở trạng thái nháp với ghi chú rằng cần xác định cách triển khai bảng mới cho tất cả các client trước.

Những gì đã xảy ra vào ngày 21 tháng 9

Đầu tiên, họ đã sửa lại quy trình xây dựng. Các phiên bản hành động được nâng cấp, Node 18 được thay bằng Node 22, và nhiệm vụ đã hoạt động trở lại — cả thủ công lẫn tự động khi có thay đổi trong quy tắc ngôn ngữ — sau đó tạo pull request với bảng đã được xây dựng lại. Tiếp theo, Tolk và bản cập nhật Tact/FunC đã được chấp nhận.

Trong quá trình cập nhật, phát hiện ra một lỗi: FunC chưa được tô màu đầy đủ. Quy tắc xử lý các toán tử hàm (_+_, _<=>_ và các dạng khác, nơi gạch dưới đại diện cho vị trí tham số) được xây dựng từ một quy tắc khác, và kết thúc bằng kiểm tra "sau đó là khoảng trắng". Trong dạng đã được xây dựng, kiểm tra này yêu cầu khoảng trắng chính xác ở vị trí mà dấu gạch dưới đóng phải xuất hiện — điều kiện không thể thỏa mãn, do đó quy tắc không bao giờ kích hoạt.

Các thay đổi còn lại không liên quan trực tiếp đến TON, nhưng giải thích tại sao một bảng duy nhất có thể hoạt động cho cả hai nền tảng. Boost đọc biểu thức theo byte, và không hiểu định dạng \uXXXX: trong lớp ký tự, biểu thức này bị chuyển thành tập hợp ký tự ASCII ngẫu nhiên. Do đó, trong ngôn ngữ Dhall, lớp toán tử đã nuốt mất chữ cái đầu tiên của mỗi tên kiểu, còn ký tự lượng từ thì không được tô màu trong bất kỳ ngôn ngữ nào có đề cập đến nó. Việc serial hóa bảng cắt bỏ byte cao nhất của các ký tự ngoài 256 ký tự đầu tiên, khiến ký tự trong BQN được nhận dạng là dấu nháy kép, thành ký tự điều khiển, còn π lại thành chữ À.

Thay đổi thứ ba liên quan đến sự khác biệt giữa các động cơ: \v được biên dịch khác nhau ở hai nền tảng — ở một nơi nó là một ký tự tab dọc, ở nơi khác là toàn bộ lớp khoảng trắng dọc cùng với ký tự xuống dòng. Điều này khiến giá trị trong file ini bị trôi ra ngoài dòng. Kiểm tra "có thể biên dịch được không" không phát hiện được vấn đề này, nên giờ đây mỗi pull request đều phải xây dựng lại bảng và kiểm tra lại gần 4.000 biểu thức trên cả hai động cơ.

Khi nào người dùng sẽ thấy thay đổi trong ứng dụng?

Thời điểm triển khai chưa được công bố ở bất kỳ đâu. Client không tải bảng từ kho lưu trữ theo thời gian thực, mà mang theo bản sao riêng, và mỗi bản sao đều cũ hơn cả ngôn ngữ TON đầu tiên trong libprisma.

ClientNguồn lấy bảngNgày bản sao
Telegram Desktopfork libprisma, được gắn như submoduletháng 4 năm 2024, bảng bên trong — tháng 11 năm 2023
Telegram cho iOSfile grammars.dat trong chính kho ứng dụng31 tháng 10 năm 2023
Telegram cho Androidfile codelng.gzip trong tài nguyên ứng dụng28 tháng 10 năm 2023

Việc cập nhật bản sao là quyết định của từng nhóm phát triển client, và trong nháp Tolk, điều này đã được nêu rõ: PR đang chờ phản hồi về cách triển khai bảng mới cho tất cả ứng dụng. Cho đến khi có phản hồi, khối mã được gán nhãn tolk, tact hay func vẫn sẽ hiển thị như hôm qua — dưới dạng văn bản đơn sắc, không tô màu.