Skip to content

Conversation

@kylewalke
Copy link

Summary

  • Add Protocol Buffers serialization for the Standard Apex Library to dramatically improve language server startup time (~10-20x faster) by eliminating ANTLR parsing at runtime
  • Implement gzip compression for the protobuf cache to reduce bundle size while maintaining fast deserialization
  • Add automatic build-time cache generation integrated into Wireit tasks, ensuring the protobuf cache is always up-to-date
  • Provide automatic fallback to ZIP-based loading if the cache is unavailable or corrupted, ensuring reliability

Test plan

  • Verify the protobuf cache is generated during npm run compile in apex-parser-ast
  • Confirm the language server starts successfully using the protobuf cache
  • Validate fallback to ZIP loading works when cache is unavailable (set forceZipFallback: true)
  • Run the comprehensive test suite: npm test in apex-parser-ast
    • Equivalence tests confirm protobuf deserialization matches ZIP parsing
    • Serializer/deserializer round-trip tests
    • Cache loader tests with various scenarios
  • Run performance benchmarks: npm run test:bench (if available)
  • Verify esbuild bundles correctly include .pb.gz files via dataurl loader

Changes Overview

Area Changes
Proto Schema New apex-stdlib.proto defining message types for StandardLibrary, TypeSymbol, MethodSymbol, VariableSymbol, etc.
Serialization stdlib-serializer.ts converts SymbolTable → protobuf binary
Deserialization stdlib-deserializer.ts converts protobuf binary → SymbolTable
Cache Loader stdlib-cache-loader.ts handles runtime loading with automatic ZIP fallback
Build Scripts generate-stdlib-cache.mjs pre-processes ~5,500 standard library classes at build time
ResourceLoader Updated to prioritize protobuf cache, with forceZipFallback option
esbuild Configs Added .pb and .pb.gz loaders across all packages for proper bundling
Tests 6 new test files covering serialization, deserialization, equivalence, compression, and cache loading

@W-20813627@

kylewalke and others added 8 commits January 14, 2026 12:27
Replaces the ZIP + on-demand parsing startup flow with a pre-serialized
Protocol Buffers binary cache for faster language server startup.

Changes:
- Add proto schema for Standard Apex Library types (apex-stdlib.proto)
- Add build-time scripts to generate protobuf TypeScript types and cache
- Add cache serializer/deserializer for converting between SymbolTable and protobuf
- Add StandardLibraryCacheLoader with automatic ZIP fallback
- Update ResourceLoader to use protobuf cache when available
- Add .pb file loaders to all esbuild configs for proper bundling
- Add comprehensive test suite for cache loading and equivalence
- Add performance benchmarks for comparing cache vs ZIP loading

The protobuf cache provides ~10-20x faster startup by eliminating ANTLR parsing.
Falls back to ZIP-based loading if cache is unavailable or corrupted.
Replaces the ZIP + on-demand parsing startup flow with a pre-serialized
Protocol Buffers binary cache for faster language server startup.

Changes:
- Add proto schema for Standard Apex Library types (apex-stdlib.proto)
- Add build-time scripts to generate protobuf TypeScript types and cache
- Add cache serializer/deserializer for converting between SymbolTable and protobuf
- Add StandardLibraryCacheLoader with automatic ZIP fallback
- Update ResourceLoader to use protobuf cache when available
- Add .pb file loaders to all esbuild configs for proper bundling
- Add comprehensive test suite for cache loading and equivalence
- Add performance benchmarks for comparing cache vs ZIP loading

The protobuf cache provides ~10-20x faster startup by eliminating ANTLR parsing.
Falls back to ZIP-based loading if cache is unavailable or corrupted.
chore(apex-parser-ast): auto-generate protobuf cache as part of compile

Restructure Wireit tasks to automatically generate protobuf stdlib cache
after TypeScript compilation. This ensures protobuf cache files are
available for tests and runtime without manual intervention.

- Rename compile task to compile:tsc (actual TypeScript compilation)
- Create compile wrapper task that depends on both compile:tsc and generate:stdlib-cache
- Update generate:stdlib-cache to depend on compile:tsc instead of compile
@kylewalke kylewalke changed the base branch from main to tdx26/main January 21, 2026 18:24
@kylewalke kylewalke changed the title Kdev/protobuf precomp artifacts W-20813627: Introduce precompiled standard apex library artifact to apex-ls Jan 21, 2026
@kylewalke kylewalke marked this pull request as ready for review January 21, 2026 18:25
@kylewalke kylewalke requested a review from a team as a code owner January 21, 2026 18:25
@kylewalke kylewalke requested a review from madhur310 January 21, 2026 18:25
@CristiCanizales CristiCanizales requested review from CristiCanizales and removed request for madhur310 January 22, 2026 00:12
peternhale and others added 4 commits January 22, 2026 09:08
…output producers (#195)

* build: refine bundle dependencies to depend directly on output producers

- Change bundle dependencies from precompile/compile to compile:tsc/generate:stdlib-cache
- Remove out/resources/** from bundle files array (tracked via precompile dependency)

This ensures bundle depends directly on the scripts that produce its required
outputs, improving wireit's dependency tracking and cache invalidation.

build: fix wireit cache invalidation for protobuf artifacts

- Remove out/resources/** from precompile output declaration
- Remove output declaration from compile script (outputs tracked via dependencies)
- Add out/resources/** and out/index.d.ts to bundle files array for esbuild resolution
- Keep resources/apex-stdlib-v*.pb.gz in bundle files array as required input

This ensures wireit properly tracks outputs through dependency chains
while still allowing esbuild to resolve required files at build time.

* refactor: move embedded ZIP loading into ResourceLoader

Move ZIP buffer loading logic from LCSAdapter into ResourceLoader's
initialize() method. ResourceLoader now handles both protobuf cache
and ZIP buffer loading internally, making it more self-contained.

- ResourceLoader.initialize() now automatically loads embedded ZIP
- Added loadEmbeddedZipBuffer() and logLoadingStatistics() methods
- LCSAdapter no longer needs to manually call setZipBuffer()
- Updated tests to reflect new internal loading behavior
@CristiCanizales
Copy link
Contributor

I guess it's not that important, but while testing locally I ran into an issue running npm run compile because this repo was in "Apex LS" folder, and the space was breaking the script like

/Users/cristina.canizales/Development/Apex: warning: directory does not exist.
Could not make proto path relative: LS/apex-language-support/packages/apex-parser-ast/src/generated: No such file or directory

@kylewalke
Copy link
Author

Seems like the compile step could use some bullet proofing to use string quote protected filepaths in case of naming including whitespaces like you mentioned. Please write up a bug for that and we can address it soon to harden the compilation process.

@kylewalke kylewalke merged commit c14db9c into tdx26/main Jan 26, 2026
13 of 14 checks passed
@kylewalke kylewalke deleted the kdev/protobufPrecompArtifacts branch January 26, 2026 19:28
@CristiCanizales
Copy link
Contributor

Seems like the compile step could use some bullet proofing to use string quote protected filepaths in case of naming including whitespaces like you mentioned. Please write up a bug for that and we can address it soon to harden the compilation process.

WI for the above mentioned: W-21045435

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants