summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorRider Linden <rider@lindenlab.com>2026-04-29 14:43:08 -0700
committerRider Linden <rider@lindenlab.com>2026-04-29 14:43:08 -0700
commit84e806f71492a76ab28e049ec255df479ffbb339 (patch)
tree3e7934f174cb271fd2fa290337fc78f099cd7395 /indra
parent364ff6e6d45087653a302b96ccd8c9e02db2b9d1 (diff)
Added support to jsonrpc server for the viewer based syntax cache.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llscripteditorws.cpp89
-rw-r--r--indra/newview/llscripteditorws.h2
-rw-r--r--indra/newview/llsyntaxid.cpp39
-rw-r--r--indra/newview/llsyntaxid.h18
4 files changed, 148 insertions, 0 deletions
diff --git a/indra/newview/llscripteditorws.cpp b/indra/newview/llscripteditorws.cpp
index 11aacd791e..3ca9be44bc 100644
--- a/indra/newview/llscripteditorws.cpp
+++ b/indra/newview/llscripteditorws.cpp
@@ -2,6 +2,9 @@
* @file llscripteditorws.cpp
* @brief JSON-RPC 2.0 WebSocket server implementation for external script editor integration
*
+ * For a full description of the JSON-RPC protocol and all supported methods,
+ * see doc/external-editor-json-rpc.md in the repository root.
+ *
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2025, Linden Research, Inc.
@@ -272,6 +275,26 @@ void LLScriptEditorWSServer::setupConnectionMethods(LLJSONRPCConnection::ptr_t c
}
return LLSD();
});
+ script_connection->registerMethod("language.syntax.cache",
+ [that](const std::string&, const LLSD&, const LLSD& params)
+ {
+ auto server = that.lock();
+ if (server)
+ {
+ return server->handleSyntaxCacheRequest();
+ }
+ return LLSD();
+ });
+ script_connection->registerMethod("language.syntax.get",
+ [that](const std::string&, const LLSD&, const LLSD& params)
+ {
+ auto server = that.lock();
+ if (server)
+ {
+ return server->handleSyntaxCacheFileRequest(params);
+ }
+ return LLSD();
+ });
script_connection->registerMethod("script.subscribe",
[that, connection_id](const std::string&, const LLSD&, const LLSD& params) -> LLSD
{
@@ -356,6 +379,71 @@ LLSD LLScriptEditorWSServer::handleSyntaxRequest(const LLSD& params) const
return response;
}
+LLSD LLScriptEditorWSServer::handleSyntaxCacheRequest() const
+{
+ LLSD response;
+ // Add array of cached syntax definition files
+ LLSD syntax_files = LLSD::emptyArray();
+ for (const auto& name : LLSyntaxDefCache::instance().getCacheFileNames())
+ {
+ syntax_files.append(name);
+ }
+ response["files"] = syntax_files;
+ response["success"] = true;
+ return response;
+}
+
+LLSD LLScriptEditorWSServer::handleSyntaxCacheFileRequest(const LLSD& params) const
+{
+ std::string filename = params["filename"].asString();
+ bool as_json = params["as_json"].asBoolean();
+
+ LLSyntaxDefCache& cache = LLSyntaxDefCache::instance();
+ LLSD response;
+
+ if (filename.empty())
+ {
+ response["error"] = "No filename specified";
+ response["success"] = false;
+ return response;
+ }
+ if (!cache.hasCacheFile(filename))
+ {
+ response["error"] = "Requested syntax cache file not found";
+ response["success"] = false;
+ return response;
+ }
+ bool success = false;
+ if (as_json)
+ {
+ LLSD file_content = cache.loadCacheFileAsLLSD(filename);
+ if (file_content.isDefined())
+ {
+ response["content"] = file_content;
+ success = true;
+ }
+ else
+ {
+ response["error"] = "Failed to load and format syntax cache file.";
+ }
+ }
+ else
+ {
+ std::string content = cache.loadCacheFile(filename);
+ if (!content.empty())
+ {
+ response["content"] = content;
+ success = true;
+ }
+ else
+ {
+ response["error"] = "Failed to load syntax cache file";
+ }
+ }
+ response["success"] = success;
+ return response;
+}
+
LLSD LLScriptEditorWSServer::handleScriptSubscribe(U32 connection_id, const LLSD& params)
{
LLSD response(LLSD::emptyMap());
@@ -716,6 +804,7 @@ void LLScriptEditorWSConnection::onOpen()
LLSD features;
features["live_sync"] = true;
features["compilation"] = true;
+ features["syntax_cache"] = true;
handshake["features"] = features;
wptr_t that = shared_from_this();
diff --git a/indra/newview/llscripteditorws.h b/indra/newview/llscripteditorws.h
index c8898c66a7..765ebe83f2 100644
--- a/indra/newview/llscripteditorws.h
+++ b/indra/newview/llscripteditorws.h
@@ -192,6 +192,8 @@ protected:
LLSD handleLanguageIdRequest() const;
LLSD handleSyntaxRequest(const LLSD &params) const;
+ LLSD handleSyntaxCacheRequest() const;
+ LLSD handleSyntaxCacheFileRequest(const LLSD& params) const;
LLSD handleScriptSubscribe(U32 connection_id, const LLSD& params);
LLSD handleScriptUnsubscribe(U32 connection_id, const LLSD& params);
LLSD handleFileWatcherFileListRequest() const;
diff --git a/indra/newview/llsyntaxid.cpp b/indra/newview/llsyntaxid.cpp
index 3d0a9d80b4..3e6fc2d217 100644
--- a/indra/newview/llsyntaxid.cpp
+++ b/indra/newview/llsyntaxid.cpp
@@ -506,6 +506,16 @@ void LLSyntaxDefCache::loadKeywordsIntoLLSD()
mSyntaxIDChangedSignal();
}
+std::vector<std::string> LLSyntaxDefCache::getCacheFileNames() const
+{
+ std::vector<std::string> names;
+ for (const auto& [name, path] : mFileCachePaths)
+ {
+ names.push_back(name);
+ }
+ return names;
+}
+
LLSD LLSyntaxDefCache::loadDeserializedCacheFile(const std::string& file_path)
{
std::ifstream file(file_path.c_str());
@@ -524,3 +534,32 @@ LLSD LLSyntaxDefCache::loadDeserializedCacheFile(const std::string& file_path)
return LLSD();
}
+std::string LLSyntaxDefCache::loadCacheFile(const std::string& name) const
+{
+ std::string full_path = mFileCachePaths.getPath(name);
+ if (!full_path.empty())
+ {
+ std::ifstream file(full_path.c_str());
+ if (file.good())
+ {
+ std::ostringstream ss;
+ ss << file.rdbuf();
+ return (file.good()) ? ss.str() : std::string();
+ }
+ else
+ {
+ LL_WARNS("SyntaxLSL") << "Failed to open cached file: " << full_path << LL_ENDL;
+ }
+ }
+ return std::string();
+}
+
+LLSD LLSyntaxDefCache::loadCacheFileAsLLSD(const std::string& name) const
+{
+ std::string full_path = mFileCachePaths.getPath(name);
+ if (!full_path.empty())
+ {
+ return loadDeserializedCacheFile(full_path);
+ }
+ return LLSD();
+}
diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h
index 3bd49378b5..b38d02c10f 100644
--- a/indra/newview/llsyntaxid.h
+++ b/indra/newview/llsyntaxid.h
@@ -80,6 +80,9 @@ public:
void clear() { mNamePathMap.clear(); }
bool empty() const { return mNamePathMap.empty(); }
+ iterator find(const std::string &name) { return mNamePathMap.find(name); }
+ const_iterator find(const std::string &name) const { return mNamePathMap.find(name); }
+
private:
name_path_map_t mNamePathMap;
};
@@ -94,6 +97,21 @@ public:
static std::string buildCacheDirectoryName(const LLUUID& syntax_id);
+ using const_iterator = cache_names_t::const_iterator;
+
+ const_iterator begin() const { return mFileCachePaths.begin(); }
+ const_iterator end() const { return mFileCachePaths.end(); }
+
+ size_t size() const { return mFileCachePaths.size(); }
+ bool empty() const { return mFileCachePaths.empty(); }
+
+ const_iterator find(const std::string& name) const { return mFileCachePaths.find(name); }
+
+ std::vector<std::string> getCacheFileNames() const;
+ bool hasCacheFile(const std::string& name) const { return mFileCachePaths.hasName(name); }
+ std::string loadCacheFile(const std::string& name) const;
+ LLSD loadCacheFileAsLLSD(const std::string& name) const;
+
protected:
void initSingleton() override;
void cleanupSingleton() override;