You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by pa...@apache.org on 2021/11/19 16:06:56 UTC

[beam] branch master updated: Merge pull request #15957 from [BEAM-13045][Playground] Implemented examples api

This is an automated email from the ASF dual-hosted git repository.

pabloem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new b9a6125  Merge pull request #15957 from [BEAM-13045][Playground] Implemented examples api
b9a6125 is described below

commit b9a6125c314d1e45918deebcfe9352e2b3adcd23
Author: daria.malkova <da...@akvelon.com>
AuthorDate: Fri Nov 19 19:05:57 2021 +0300

    Merge pull request #15957 from [BEAM-13045][Playground] Implemented examples api
    
    * Add reading of precompiled objects from public bucket
    
    * Change the enum PrecompiledObjectType
    
    * RAT for pb.dart
    
    * [Playground][BEAM-12941][Bugfix] Fix workflows for playground applications (#83)
    
    * Update workflows for playground
    
    * Attempt to fix tests
    
    * Remove continue on error to catch errors
    
    * Fix linter problem for backend dockerfile
    
    * Update folder to run backend go linter
    
    * Moved flutter test to execution via gradle tasks
    
    * Revert "[Playground][BEAM-12941][Bugfix] Fix workflows for playground applications (#83)" (#88)
    
    This reverts commit b73f5f70ac4184b56a0a03922731c5f2f69b9566.
    
    * Add info about meta file
    
    Co-authored-by: Sergey Kalinin <91...@users.noreply.github.com>
    Co-authored-by: Ilya <il...@akvelon.com>
    Co-authored-by: Aydar Zainutdinov <ay...@akvelon.com>
---
 playground/api/v1/api.proto                        |  52 ++-
 playground/backend/cmd/server/controller.go        | 383 +++++++++++++++-
 playground/backend/go.mod                          |   2 +
 playground/backend/go.sum                          |  90 +++-
 playground/backend/internal/api/v1/api.pb.go       | 502 +++++++++++----------
 playground/backend/internal/api/v1/api_grpc.pb.go  |  94 ++--
 .../internal/cloud_bucket/precompiled_objects.go   | 278 ++++++++++++
 .../cloud_bucket/precompiled_objects_test.go       | 222 +++++++++
 playground/frontend/lib/api/v1/api.pb.dart         | 190 ++++----
 playground/frontend/lib/api/v1/api.pbenum.dart     |  24 +-
 playground/frontend/lib/api/v1/api.pbgrpc.dart     | 129 +++---
 playground/frontend/lib/api/v1/api.pbjson.dart     |  79 ++--
 12 files changed, 1492 insertions(+), 553 deletions(-)

diff --git a/playground/api/v1/api.proto b/playground/api/v1/api.proto
index ea0455a..47b4970 100644
--- a/playground/api/v1/api.proto
+++ b/playground/api/v1/api.proto
@@ -45,10 +45,11 @@ enum Status {
   STATUS_CANCELED = 12;
 }
 
-enum ExampleType {
-  EXAMPLE_TYPE_DEFAULT = 0;
-  EXAMPLE_TYPE_KATA = 1;
-  EXAMPLE_TYPE_UNIT_TEST = 2;
+enum PrecompiledObjectType {
+  PRECOMPILED_OBJECT_TYPE_UNSPECIFIED = 0;
+  PRECOMPILED_OBJECT_TYPE_EXAMPLE = 1;
+  PRECOMPILED_OBJECT_TYPE_KATA = 2;
+  PRECOMPILED_OBJECT_TYPE_UNIT_TEST = 3;
 }
 
 // RunCodeRequest represents a code text and options of SDK which executes the code.
@@ -112,42 +113,43 @@ message CancelRequest {
 message CancelResponse {
 }
 
-// ListOfExamplesRequest contains information of the needed examples sdk and categories.
-message GetListOfExamplesRequest{
+// GetPrecompiledObjectsRequest contains information of the needed PrecompiledObjects sdk and categories.
+message GetPrecompiledObjectsRequest{
   Sdk sdk = 1;
   string category = 2;
 }
 
-// Example represents one example with its information
-message Example{
-  string example_uuid = 1;
+// PrecompiledObject represents one PrecompiledObject with its information
+message PrecompiledObject{
+  string cloud_path = 1;
   string name = 2;
   string description = 3;
-  ExampleType type = 4;
+  PrecompiledObjectType type = 4;
 }
 
 // Categories represent the array of messages with sdk and categories at this sdk
 message Categories{
   message Category{
     string category_name = 1;
-    repeated Example examples = 2;
+    repeated PrecompiledObject precompiled_objects = 2;
   }
   Sdk sdk = 1;
   repeated Category categories = 2;
 }
 
-// ListOfExamplesResponse represent the map between sdk and categories for the sdk.
-message GetListOfExamplesResponse{
-  repeated Categories sdk_examples = 1;
+
+// GetListOfPrecompiledObjectsResponse represent the map between sdk and categories for the sdk.
+message GetPrecompiledObjectsResponse{
+  repeated Categories sdk_categories = 1;
 }
 
-// ExampleRequest contains information of the example uuid.
-message GetExampleRequest{
-  string example_uuid = 1;
+// GetPrecompiledObjectRequest contains information of the PrecompiledObject uuid.
+message GetPrecompiledObjectRequest{
+  string cloud_path = 1;
 }
 
-// ExampleResponse represents the source code of the example.
-message GetExampleResponse{
+// GetPrecompiledObjectResponse represents the source code of the PrecompiledObject.
+message GetPrecompiledObjectCodeResponse{
   string code = 1;
 }
 
@@ -171,12 +173,12 @@ service PlaygroundService {
   // Cancel code processing
   rpc Cancel(CancelRequest) returns (CancelResponse);
 
-  // Get the list of precompiled examples.
-  rpc GetListOfExamples(GetListOfExamplesRequest) returns (GetListOfExamplesResponse);
+  // Get all precompiled objects from the cloud storage.
+  rpc GetPrecompiledObjects(GetPrecompiledObjectsRequest) returns (GetPrecompiledObjectsResponse);
 
-  // Get the code of an example.
-  rpc GetExample(GetExampleRequest) returns (GetExampleResponse);
+  // Get the code of an PrecompiledObject.
+  rpc GetPrecompiledObjectCode(GetPrecompiledObjectRequest) returns (GetPrecompiledObjectCodeResponse);
 
-  // Get the precompiled details of an example.
-  rpc GetExampleOutput(GetExampleRequest) returns (GetRunOutputResponse);
+  // Get the precompiled details of an PrecompiledObject.
+  rpc GetPrecompiledObjectOutput(GetPrecompiledObjectRequest) returns (GetRunOutputResponse);
 }
diff --git a/playground/backend/cmd/server/controller.go b/playground/backend/cmd/server/controller.go
index 9c578b2..61b581a 100644
--- a/playground/backend/cmd/server/controller.go
+++ b/playground/backend/cmd/server/controller.go
@@ -17,6 +17,7 @@ package main
 import (
 	pb "beam.apache.org/playground/backend/internal/api/v1"
 	"beam.apache.org/playground/backend/internal/cache"
+	"beam.apache.org/playground/backend/internal/cloud_bucket"
 	"beam.apache.org/playground/backend/internal/code_processing"
 	"beam.apache.org/playground/backend/internal/environment"
 	"beam.apache.org/playground/backend/internal/errors"
@@ -154,36 +155,372 @@ func (controller *playgroundController) Cancel(ctx context.Context, info *pb.Can
 	return &pb.CancelResponse{}, nil
 }
 
-// GetListOfExamples returns the list of examples
-func (controller *playgroundController) GetListOfExamples(ctx context.Context, info *pb.GetListOfExamplesRequest) (*pb.GetListOfExamplesResponse, error) {
-	// TODO implement this method
-	example1 := pb.Example{ExampleUuid: "001", Name: "Example1", Description: "Test example 1", Type: pb.ExampleType_EXAMPLE_TYPE_DEFAULT}
-	example2 := pb.Example{ExampleUuid: "003", Name: "Example3", Description: "Test example 3", Type: pb.ExampleType_EXAMPLE_TYPE_KATA}
-
-	cat1 := pb.Categories_Category{
-		CategoryName: "Common",
-		Examples:     []*pb.Example{&example1, {ExampleUuid: "002", Name: "Example2", Description: "Test example 1", Type: pb.ExampleType_EXAMPLE_TYPE_UNIT_TEST}},
+// GetPrecompiledObjects returns the list of examples
+func (controller *playgroundController) GetPrecompiledObjects(ctx context.Context, info *pb.GetPrecompiledObjectsRequest) (*pb.GetPrecompiledObjectsResponse, error) {
+	bucket := cloud_bucket.New()
+	sdkToCategories, err := bucket.GetPrecompiledObjects(ctx, info.Sdk, info.Category)
+	if err != nil {
+		logger.Errorf("%s: GetPrecompiledObjects(): cloud storage error: %s", err.Error())
+		return nil, errors.InternalError("GetPrecompiledObjects(): ", err.Error())
 	}
-	cat2 := pb.Categories_Category{
-		CategoryName: "I/O",
-		Examples:     []*pb.Example{&example2},
+	response := pb.GetPrecompiledObjectsResponse{SdkCategories: make([]*pb.Categories, 0)}
+	for sdkName, categories := range *sdkToCategories {
+		sdkCategory := pb.Categories{Sdk: pb.Sdk(pb.Sdk_value[sdkName]), Categories: make([]*pb.Categories_Category, 0)}
+		for categoryName, precompiledObjects := range categories {
+			PutPrecompiledObjectsToCategory(categoryName, &precompiledObjects, &sdkCategory)
+		}
+		response.SdkCategories = append(response.SdkCategories, &sdkCategory)
 	}
-	javaCats := pb.Categories{Sdk: pb.Sdk_SDK_JAVA, Categories: []*pb.Categories_Category{&cat1, &cat2}}
-	goCats := pb.Categories{Sdk: pb.Sdk_SDK_GO, Categories: []*pb.Categories_Category{&cat1, &cat2}}
-	response := pb.GetListOfExamplesResponse{SdkExamples: []*pb.Categories{&javaCats, &goCats}}
 	return &response, nil
 }
 
-// GetExample returns the code of the specific example
-func (controller *playgroundController) GetExample(ctx context.Context, info *pb.GetExampleRequest) (*pb.GetExampleResponse, error) {
-	// TODO implement this method
-	response := pb.GetExampleResponse{Code: "example code"}
+// GetPrecompiledObjectCode returns the code of the specific example
+func (controller *playgroundController) GetPrecompiledObjectCode(ctx context.Context, info *pb.GetPrecompiledObjectRequest) (*pb.GetPrecompiledObjectCodeResponse, error) {
+	cd := cloud_bucket.New()
+	codeString, err := cd.GetPrecompiledObject(ctx, info.GetCloudPath())
+	if err != nil {
+		logger.Errorf("%s: GetPrecompiledObject(): cloud storage error: %s", err.Error())
+		return nil, errors.InternalError("GetPrecompiledObjects(): ", err.Error())
+	}
+	response := pb.GetPrecompiledObjectCodeResponse{Code: *codeString}
 	return &response, nil
 }
 
-// GetExampleOutput returns the output of the compiled and run example
-func (controller *playgroundController) GetExampleOutput(ctx context.Context, info *pb.GetExampleRequest) (*pb.GetRunOutputResponse, error) {
-	// TODO implement this method
-	response := pb.GetRunOutputResponse{Output: "Response Output"}
+// GetPrecompiledObjectOutput returns the output of the compiled and run example
+func (controller *playgroundController) GetPrecompiledObjectOutput(ctx context.Context, info *pb.GetPrecompiledObjectRequest) (*pb.GetRunOutputResponse, error) {
+	cd := cloud_bucket.New()
+	output, err := cd.GetPrecompiledObjectOutput(ctx, info.GetCloudPath())
+	if err != nil {
+		logger.Errorf("%s: GetPrecompiledObjectOutput(): cloud storage error: %s", err.Error())
+		return nil, errors.InternalError("GetPrecompiledObjectOutput(): ", err.Error())
+	}
+	response := pb.GetRunOutputResponse{Output: *output}
 	return &response, nil
 }
+
+// PutPrecompiledObjectsToCategory adds categories with precompiled objects to protobuf object
+func PutPrecompiledObjectsToCategory(categoryName string, precompiledObjects *cloud_bucket.PrecompiledObjects, sdkCategory *pb.Categories) {
+	category := pb.Categories_Category{
+		CategoryName:       categoryName,
+		PrecompiledObjects: make([]*pb.PrecompiledObject, 0),
+	}
+	for _, object := range *precompiledObjects {
+		category.PrecompiledObjects = append(category.PrecompiledObjects, &pb.PrecompiledObject{
+			CloudPath:   object.CloudPath,
+			Name:        object.Name,
+			Description: object.Description,
+			Type:        object.Type,
+		})
+	}
+	sdkCategory.Categories = append(sdkCategory.Categories, &category)
+}
+
+// setupLifeCycle creates fs_tool.LifeCycle and prepares files and folders needed to code processing
+func setupLifeCycle(sdk pb.Sdk, code string, pipelineId uuid.UUID, workingDir string) (*fs_tool.LifeCycle, error) {
+	// create file system service
+	lc, err := fs_tool.NewLifeCycle(sdk, pipelineId, workingDir)
+	if err != nil {
+		logger.Errorf("%s: RunCode(): NewLifeCycle(): %s\n", pipelineId, err.Error())
+		return nil, err
+	}
+
+	// create folders
+	err = lc.CreateFolders()
+	if err != nil {
+		logger.Errorf("%s: RunCode(): CreateFolders(): %s\n", pipelineId, err.Error())
+		return nil, err
+	}
+
+	// create file with code
+	_, err = lc.CreateExecutableFile(code)
+	if err != nil {
+		logger.Errorf("%s: RunCode(): CreateExecutableFile(): %s\n", pipelineId, err.Error())
+		return nil, err
+	}
+	return lc, nil
+}
+
+// setupCompileBuilder returns executors.CompileBuilder with validators and compiler based on sdk
+func setupCompileBuilder(lc *fs_tool.LifeCycle, sdk pb.Sdk, executorConfig *environment.ExecutorConfig) *executors.CompileBuilder {
+	filePath := lc.GetAbsoluteExecutableFilePath()
+	val := setupValidators(sdk, filePath)
+
+	compileBuilder := executors.NewExecutorBuilder().
+		WithValidator().
+		WithSdkValidators(val).
+		WithCompiler()
+
+	switch sdk {
+	case pb.Sdk_SDK_JAVA:
+		workingDir := lc.GetAbsoluteExecutableFilesFolderPath()
+
+		compileBuilder = compileBuilder.
+			WithCommand(executorConfig.CompileCmd).
+			WithArgs(executorConfig.CompileArgs).
+			WithFileName(filePath).
+			WithWorkingDir(workingDir)
+	}
+	return compileBuilder
+}
+
+// setupRunBuilder returns executors.RunBuilder based on sdk
+func setupRunBuilder(pipelineId uuid.UUID, lc *fs_tool.LifeCycle, sdk pb.Sdk, env *environment.Environment, compileBuilder *executors.CompileBuilder) (*executors.RunBuilder, error) {
+	runBuilder := compileBuilder.
+		WithRunner().
+		WithCommand(env.BeamSdkEnvs.ExecutorConfig.RunCmd).
+		WithArgs(env.BeamSdkEnvs.ExecutorConfig.RunArgs).
+		WithWorkingDir(lc.GetAbsoluteExecutableFilesFolderPath())
+
+	switch sdk {
+	case pb.Sdk_SDK_JAVA:
+		className, err := lc.ExecutableName(pipelineId, env.ApplicationEnvs.WorkingDir())
+		if err != nil {
+			logger.Errorf("%s: get executable file name: %s\n", pipelineId, err.Error())
+			return nil, err
+		}
+
+		runBuilder = runBuilder.
+			WithClassName(className)
+	}
+	return runBuilder, nil
+}
+
+// setupValidators returns slice of validators.Validator based on sdk
+func setupValidators(sdk pb.Sdk, filepath string) *[]validators.Validator {
+	var val *[]validators.Validator
+	switch sdk {
+	case pb.Sdk_SDK_JAVA:
+		val = validators.GetJavaValidators(filepath)
+	}
+	return val
+}
+
+// processCode validates, compiles and runs code by pipelineId.
+// During each operation updates status of execution and saves it into cache:
+// - In case of processing works more that timeout duration saves playground.Status_STATUS_RUN_TIMEOUT as cache.Status into cache.
+// - In case of code processing has been canceled saves playground.Status_STATUS_CANCELED as cache.Status into cache.
+// - In case of validation step is failed saves playground.Status_STATUS_VALIDATION_ERROR as cache.Status into cache.
+// - In case of compile step is failed saves playground.Status_STATUS_COMPILE_ERROR as cache.Status and compile logs as cache.CompileOutput into cache.
+// - In case of compile step is completed with no errors saves compile output as cache.CompileOutput into cache.
+// - In case of run step is failed saves playground.Status_STATUS_RUN_ERROR as cache.Status and run logs as cache.RunError into cache.
+// - In case of run step is completed with no errors saves playground.Status_STATUS_FINISHED as cache.Status and run output as cache.RunOutput into cache.
+// At the end of this method deletes all created folders.
+func processCode(ctx context.Context, cacheService cache.Cache, lc *fs_tool.LifeCycle, compileBuilder *executors.CompileBuilder, pipelineId uuid.UUID, env *environment.Environment, sdk pb.Sdk) {
+	ctxWithTimeout, finishCtxFunc := context.WithTimeout(ctx, env.ApplicationEnvs.PipelineExecuteTimeout())
+	defer func(lc *fs_tool.LifeCycle) {
+		finishCtxFunc()
+		cleanUp(pipelineId, lc)
+	}(lc)
+
+	errorChannel := make(chan error, 1)
+	dataChannel := make(chan interface{}, 1)
+	successChannel := make(chan bool, 1)
+	cancelChannel := make(chan bool, 1)
+
+	go cancelCheck(ctxWithTimeout, pipelineId, cancelChannel, cacheService)
+
+	// build executor for validate and compile steps
+	exec := compileBuilder.Build()
+
+	// validate
+	logger.Infof("%s: Validate() ...\n", pipelineId)
+	validateFunc := exec.Validate()
+	go validateFunc(successChannel, errorChannel)
+
+	if !processStep(ctxWithTimeout, pipelineId, cacheService, cancelChannel, successChannel, nil, errorChannel, pb.Status_STATUS_VALIDATION_ERROR, pb.Status_STATUS_PREPARING) {
+		return
+	}
+
+	// prepare
+	logger.Infof("%s: Prepare() ...\n", pipelineId)
+	prepareFunc := exec.Prepare()
+	go prepareFunc(successChannel, errorChannel)
+
+	if !processStep(ctxWithTimeout, pipelineId, cacheService, cancelChannel, successChannel, nil, errorChannel, pb.Status_STATUS_PREPARATION_ERROR, pb.Status_STATUS_COMPILING) {
+		return
+	}
+
+	// compile
+	logger.Infof("%s: Compile() ...\n", pipelineId)
+	compileCmd := exec.Compile(ctxWithTimeout)
+	go func(successCh chan bool, errCh chan error, dataCh chan interface{}) {
+		// TODO separate stderr from stdout
+		data, err := compileCmd.CombinedOutput()
+		dataCh <- data
+		if err != nil {
+			errCh <- err
+			successCh <- false
+		} else {
+			successCh <- true
+		}
+	}(successChannel, errorChannel, dataChannel)
+
+	if !processStep(ctxWithTimeout, pipelineId, cacheService, cancelChannel, successChannel, dataChannel, errorChannel, pb.Status_STATUS_COMPILE_ERROR, pb.Status_STATUS_EXECUTING) {
+		return
+	}
+
+	runBuilder, err := setupRunBuilder(pipelineId, lc, sdk, env, compileBuilder)
+	if err != nil {
+		logger.Errorf("%s: error during setup runBuilder: %s\n", pipelineId, err.Error())
+		setToCache(ctxWithTimeout, cacheService, pipelineId, cache.Status, pb.Status_STATUS_ERROR)
+		return
+	}
+
+	// build executor for run step
+	exec = runBuilder.Build()
+
+	// run
+	logger.Infof("%s: Run() ...\n", pipelineId)
+	runCmd := exec.Run(ctxWithTimeout)
+	go func(successCh chan bool, errCh chan error, dataCh chan interface{}) {
+		// TODO separate stderr from stdout
+		data, err := runCmd.CombinedOutput()
+		dataCh <- data
+		if err != nil {
+			errCh <- err
+			successChannel <- false
+		} else {
+			successChannel <- true
+		}
+	}(successChannel, errorChannel, dataChannel)
+
+	processStep(ctxWithTimeout, pipelineId, cacheService, cancelChannel, successChannel, dataChannel, errorChannel, pb.Status_STATUS_RUN_ERROR, pb.Status_STATUS_FINISHED)
+}
+
+// processStep processes each executor's step with cancel and timeout checks.
+// If finishes by canceling, timeout or error - returns false.
+// If finishes successfully returns true.
+func processStep(ctx context.Context, pipelineId uuid.UUID, cacheService cache.Cache, cancelChannel, successChannel chan bool, dataChannel chan interface{}, errorChannel chan error, errorCaseStatus, successCaseStatus pb.Status) bool {
+	select {
+	case <-ctx.Done():
+		finishByTimeout(ctx, pipelineId, cacheService)
+		return false
+	case <-cancelChannel:
+		processCancel(ctx, cacheService, pipelineId)
+		return false
+	case ok := <-successChannel:
+		var data []byte = nil
+		if dataChannel != nil {
+			temp := <-dataChannel
+			data = temp.([]byte)
+		}
+		if !ok {
+			err := <-errorChannel
+			processError(ctx, err, data, pipelineId, cacheService, errorCaseStatus)
+			return false
+		}
+		processSuccess(ctx, data, pipelineId, cacheService, successCaseStatus)
+	}
+	return true
+}
+
+// finishByTimeout is used in case of runCode method finished by timeout
+func finishByTimeout(ctx context.Context, pipelineId uuid.UUID, cacheService cache.Cache) {
+	logger.Errorf("%s: processCode finish because of timeout\n", pipelineId)
+
+	// set to cache pipelineId: cache.SubKey_Status: Status_STATUS_RUN_TIMEOUT
+	setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_RUN_TIMEOUT)
+}
+
+// cancelCheck checks cancel flag for code processing.
+// If cancel flag doesn't exist in cache continue working.
+// If context is done it means that code processing was finished (successfully/with error/timeout). Return.
+// If cancel flag exists, and it is true it means that code processing was canceled. Set true to cancelChannel and return.
+func cancelCheck(ctx context.Context, pipelineId uuid.UUID, cancelChannel chan bool, cacheService cache.Cache) {
+	ticker := time.NewTicker(500 * time.Millisecond)
+	for {
+		select {
+		case <-ctx.Done():
+			ticker.Stop()
+			return
+		case _ = <-ticker.C:
+			cancel, err := cacheService.GetValue(ctx, pipelineId, cache.Canceled)
+			if err != nil {
+				continue
+			}
+			if cancel.(bool) {
+				cancelChannel <- true
+			}
+			return
+		}
+	}
+}
+
+// cleanUp removes all prepared folders for received LifeCycle
+func cleanUp(pipelineId uuid.UUID, lc *fs_tool.LifeCycle) {
+	logger.Infof("%s: DeleteFolders() ...\n", pipelineId)
+	if err := lc.DeleteFolders(); err != nil {
+		logger.Error("%s: DeleteFolders(): %s\n", pipelineId, err.Error())
+	}
+	logger.Infof("%s: DeleteFolders() complete\n", pipelineId)
+	logger.Infof("%s: complete\n", pipelineId)
+}
+
+// processError processes error received during processing code via setting a corresponding status and output to cache
+func processError(ctx context.Context, err error, data []byte, pipelineId uuid.UUID, cacheService cache.Cache, status pb.Status) {
+	switch status {
+	case pb.Status_STATUS_VALIDATION_ERROR:
+		logger.Errorf("%s: Validate(): %s\n", pipelineId, err.Error())
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_VALIDATION_ERROR)
+	case pb.Status_STATUS_PREPARATION_ERROR:
+		logger.Errorf("%s: Prepare(): %s\n", pipelineId, err.Error())
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_PREPARATION_ERROR)
+	case pb.Status_STATUS_COMPILE_ERROR:
+		logger.Errorf("%s: Compile(): err: %s, output: %s\n", pipelineId, err.Error(), data)
+
+		setToCache(ctx, cacheService, pipelineId, cache.CompileOutput, "error: "+err.Error()+", output: "+string(data))
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_COMPILE_ERROR)
+	case pb.Status_STATUS_RUN_ERROR:
+		logger.Errorf("%s: Run(): err: %s, output: %s\n", pipelineId, err.Error(), data)
+
+		setToCache(ctx, cacheService, pipelineId, cache.RunError, "error: "+err.Error()+", output: "+string(data))
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_RUN_ERROR)
+	}
+}
+
+// processSuccess processes case after successful code processing via setting a corresponding status and output to cache
+func processSuccess(ctx context.Context, output []byte, pipelineId uuid.UUID, cacheService cache.Cache, status pb.Status) {
+	switch status {
+	case pb.Status_STATUS_PREPARING:
+		logger.Infof("%s: Validate() finish\n", pipelineId)
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_PREPARING)
+	case pb.Status_STATUS_COMPILING:
+		logger.Infof("%s: Prepare() finish\n", pipelineId)
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_COMPILING)
+	case pb.Status_STATUS_EXECUTING:
+		logger.Infof("%s: Compile() finish\n", pipelineId)
+
+		setToCache(ctx, cacheService, pipelineId, cache.CompileOutput, string(output))
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_EXECUTING)
+	case pb.Status_STATUS_FINISHED:
+		logger.Infof("%s: Run() finish\n", pipelineId)
+
+		setToCache(ctx, cacheService, pipelineId, cache.RunOutput, string(output))
+
+		setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_FINISHED)
+	}
+}
+
+// processCancel process case when code processing was canceled
+func processCancel(ctx context.Context, cacheService cache.Cache, pipelineId uuid.UUID) {
+	logger.Infof("%s: was canceled\n", pipelineId)
+
+	// set to cache pipelineId: cache.SubKey_Status: pb.Status_STATUS_CANCELED
+	setToCache(ctx, cacheService, pipelineId, cache.Status, pb.Status_STATUS_CANCELED)
+}
+
+// setToCache puts value to cache by key and subKey
+func setToCache(ctx context.Context, cacheService cache.Cache, key uuid.UUID, subKey cache.SubKey, value interface{}) error {
+	err := cacheService.SetValue(ctx, key, subKey, value)
+	if err != nil {
+		logger.Errorf("%s: cache.SetValue: %s\n", key, err.Error())
+	}
+	return err
+}
diff --git a/playground/backend/go.mod b/playground/backend/go.mod
index 17634bc..8a619ef 100644
--- a/playground/backend/go.mod
+++ b/playground/backend/go.mod
@@ -19,12 +19,14 @@ go 1.16
 
 require (
 	cloud.google.com/go/logging v1.4.2
+	cloud.google.com/go/storage v1.18.2
 	github.com/go-redis/redis/v8 v8.11.4
 	github.com/go-redis/redismock/v8 v8.0.6
 	github.com/google/uuid v1.3.0
 	github.com/improbable-eng/grpc-web v0.14.1
 	github.com/rs/cors v1.8.0
 	go.uber.org/goleak v1.1.12
+	google.golang.org/api v0.58.0
 	google.golang.org/grpc v1.41.0
 	google.golang.org/protobuf v1.27.1
 )
diff --git a/playground/backend/go.sum b/playground/backend/go.sum
index b7e202b..8405565 100644
--- a/playground/backend/go.sum
+++ b/playground/backend/go.sum
@@ -17,8 +17,15 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP
 cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
 cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
 cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
 cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
+cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
+cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
+cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
+cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
+cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
+cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
+cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -38,10 +45,13 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.18.2 h1:5NQw6tOn3eMm0oE8vTkfjau18kjL79FlMjy/CHTpmoY=
+cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@@ -68,6 +78,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
 github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
 github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -79,6 +91,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
@@ -107,6 +120,7 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
 github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -171,6 +185,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
 github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -190,6 +205,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -206,9 +222,12 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
+github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@@ -220,14 +239,19 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
+github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
+github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@@ -278,7 +302,6 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
 github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -415,6 +438,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -501,8 +525,9 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -513,7 +538,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -575,8 +599,12 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1 h1:B333XXssMuKQeBwiNODx4TupZy7bf4sxFZnN2ZOcvUE=
+golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -648,8 +676,16 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw=
+golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -717,6 +753,10 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -746,8 +786,17 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
 google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
 google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
 google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU=
 google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I=
+google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
+google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
+google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
+google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
+google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
+google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
+google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
+google.golang.org/api v0.58.0 h1:MDkAbYIB1JpSgCTOCYYoIec/coMlKK4oVbpnBLLcyT0=
+google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -801,8 +850,26 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D
 google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
 google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
-google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a h1:VA0wtJaR+W1I11P2f535J7D/YxyvEFMTMvcmyeZ9FBE=
+google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
 google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
+google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
+google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
+google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
+google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
+google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211016002631-37fc39342514 h1:Rp1vYDPD4TdkMH5S/bZbopsGCsWhPcrLBUwOVhAQCxM=
+google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@@ -830,8 +897,13 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
 google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
 google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
 google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
 google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/playground/backend/internal/api/v1/api.pb.go b/playground/backend/internal/api/v1/api.pb.go
index 5701de1..67a7ff6 100644
--- a/playground/backend/internal/api/v1/api.pb.go
+++ b/playground/backend/internal/api/v1/api.pb.go
@@ -171,52 +171,55 @@ func (Status) EnumDescriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{1}
 }
 
-type ExampleType int32
+type PrecompiledObjectType int32
 
 const (
-	ExampleType_EXAMPLE_TYPE_DEFAULT   ExampleType = 0
-	ExampleType_EXAMPLE_TYPE_KATA      ExampleType = 1
-	ExampleType_EXAMPLE_TYPE_UNIT_TEST ExampleType = 2
+	PrecompiledObjectType_PRECOMPILED_OBJECT_TYPE_UNSPECIFIED PrecompiledObjectType = 0
+	PrecompiledObjectType_PRECOMPILED_OBJECT_TYPE_EXAMPLE     PrecompiledObjectType = 1
+	PrecompiledObjectType_PRECOMPILED_OBJECT_TYPE_KATA        PrecompiledObjectType = 2
+	PrecompiledObjectType_PRECOMPILED_OBJECT_TYPE_UNIT_TEST   PrecompiledObjectType = 3
 )
 
-// Enum value maps for ExampleType.
+// Enum value maps for PrecompiledObjectType.
 var (
-	ExampleType_name = map[int32]string{
-		0: "EXAMPLE_TYPE_DEFAULT",
-		1: "EXAMPLE_TYPE_KATA",
-		2: "EXAMPLE_TYPE_UNIT_TEST",
-	}
-	ExampleType_value = map[string]int32{
-		"EXAMPLE_TYPE_DEFAULT":   0,
-		"EXAMPLE_TYPE_KATA":      1,
-		"EXAMPLE_TYPE_UNIT_TEST": 2,
+	PrecompiledObjectType_name = map[int32]string{
+		0: "PRECOMPILED_OBJECT_TYPE_UNSPECIFIED",
+		1: "PRECOMPILED_OBJECT_TYPE_EXAMPLE",
+		2: "PRECOMPILED_OBJECT_TYPE_KATA",
+		3: "PRECOMPILED_OBJECT_TYPE_UNIT_TEST",
+	}
+	PrecompiledObjectType_value = map[string]int32{
+		"PRECOMPILED_OBJECT_TYPE_UNSPECIFIED": 0,
+		"PRECOMPILED_OBJECT_TYPE_EXAMPLE":     1,
+		"PRECOMPILED_OBJECT_TYPE_KATA":        2,
+		"PRECOMPILED_OBJECT_TYPE_UNIT_TEST":   3,
 	}
 )
 
-func (x ExampleType) Enum() *ExampleType {
-	p := new(ExampleType)
+func (x PrecompiledObjectType) Enum() *PrecompiledObjectType {
+	p := new(PrecompiledObjectType)
 	*p = x
 	return p
 }
 
-func (x ExampleType) String() string {
+func (x PrecompiledObjectType) String() string {
 	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
 }
 
-func (ExampleType) Descriptor() protoreflect.EnumDescriptor {
+func (PrecompiledObjectType) Descriptor() protoreflect.EnumDescriptor {
 	return file_api_v1_api_proto_enumTypes[2].Descriptor()
 }
 
-func (ExampleType) Type() protoreflect.EnumType {
+func (PrecompiledObjectType) Type() protoreflect.EnumType {
 	return &file_api_v1_api_proto_enumTypes[2]
 }
 
-func (x ExampleType) Number() protoreflect.EnumNumber {
+func (x PrecompiledObjectType) Number() protoreflect.EnumNumber {
 	return protoreflect.EnumNumber(x)
 }
 
-// Deprecated: Use ExampleType.Descriptor instead.
-func (ExampleType) EnumDescriptor() ([]byte, []int) {
+// Deprecated: Use PrecompiledObjectType.Descriptor instead.
+func (PrecompiledObjectType) EnumDescriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{2}
 }
 
@@ -803,8 +806,8 @@ func (*CancelResponse) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{11}
 }
 
-// ListOfExamplesRequest contains information of the needed examples sdk and categories.
-type GetListOfExamplesRequest struct {
+// GetPrecompiledObjectsRequest contains information of the needed PrecompiledObjects sdk and categories.
+type GetPrecompiledObjectsRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -813,8 +816,8 @@ type GetListOfExamplesRequest struct {
 	Category string `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"`
 }
 
-func (x *GetListOfExamplesRequest) Reset() {
-	*x = GetListOfExamplesRequest{}
+func (x *GetPrecompiledObjectsRequest) Reset() {
+	*x = GetPrecompiledObjectsRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_v1_api_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -822,13 +825,13 @@ func (x *GetListOfExamplesRequest) Reset() {
 	}
 }
 
-func (x *GetListOfExamplesRequest) String() string {
+func (x *GetPrecompiledObjectsRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetListOfExamplesRequest) ProtoMessage() {}
+func (*GetPrecompiledObjectsRequest) ProtoMessage() {}
 
-func (x *GetListOfExamplesRequest) ProtoReflect() protoreflect.Message {
+func (x *GetPrecompiledObjectsRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_v1_api_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -840,39 +843,39 @@ func (x *GetListOfExamplesRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetListOfExamplesRequest.ProtoReflect.Descriptor instead.
-func (*GetListOfExamplesRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPrecompiledObjectsRequest.ProtoReflect.Descriptor instead.
+func (*GetPrecompiledObjectsRequest) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{12}
 }
 
-func (x *GetListOfExamplesRequest) GetSdk() Sdk {
+func (x *GetPrecompiledObjectsRequest) GetSdk() Sdk {
 	if x != nil {
 		return x.Sdk
 	}
 	return Sdk_SDK_UNSPECIFIED
 }
 
-func (x *GetListOfExamplesRequest) GetCategory() string {
+func (x *GetPrecompiledObjectsRequest) GetCategory() string {
 	if x != nil {
 		return x.Category
 	}
 	return ""
 }
 
-// Example represents one example with its information
-type Example struct {
+// PrecompiledObject represents one PrecompiledObject with its information
+type PrecompiledObject struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ExampleUuid string      `protobuf:"bytes,1,opt,name=example_uuid,json=exampleUuid,proto3" json:"example_uuid,omitempty"`
-	Name        string      `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
-	Description string      `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
-	Type        ExampleType `protobuf:"varint,4,opt,name=type,proto3,enum=api.v1.ExampleType" json:"type,omitempty"`
+	CloudPath   string                `protobuf:"bytes,1,opt,name=cloud_path,json=cloudPath,proto3" json:"cloud_path,omitempty"`
+	Name        string                `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Description string                `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	Type        PrecompiledObjectType `protobuf:"varint,4,opt,name=type,proto3,enum=api.v1.PrecompiledObjectType" json:"type,omitempty"`
 }
 
-func (x *Example) Reset() {
-	*x = Example{}
+func (x *PrecompiledObject) Reset() {
+	*x = PrecompiledObject{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_v1_api_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -880,13 +883,13 @@ func (x *Example) Reset() {
 	}
 }
 
-func (x *Example) String() string {
+func (x *PrecompiledObject) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*Example) ProtoMessage() {}
+func (*PrecompiledObject) ProtoMessage() {}
 
-func (x *Example) ProtoReflect() protoreflect.Message {
+func (x *PrecompiledObject) ProtoReflect() protoreflect.Message {
 	mi := &file_api_v1_api_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -898,37 +901,37 @@ func (x *Example) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use Example.ProtoReflect.Descriptor instead.
-func (*Example) Descriptor() ([]byte, []int) {
+// Deprecated: Use PrecompiledObject.ProtoReflect.Descriptor instead.
+func (*PrecompiledObject) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{13}
 }
 
-func (x *Example) GetExampleUuid() string {
+func (x *PrecompiledObject) GetCloudPath() string {
 	if x != nil {
-		return x.ExampleUuid
+		return x.CloudPath
 	}
 	return ""
 }
 
-func (x *Example) GetName() string {
+func (x *PrecompiledObject) GetName() string {
 	if x != nil {
 		return x.Name
 	}
 	return ""
 }
 
-func (x *Example) GetDescription() string {
+func (x *PrecompiledObject) GetDescription() string {
 	if x != nil {
 		return x.Description
 	}
 	return ""
 }
 
-func (x *Example) GetType() ExampleType {
+func (x *PrecompiledObject) GetType() PrecompiledObjectType {
 	if x != nil {
 		return x.Type
 	}
-	return ExampleType_EXAMPLE_TYPE_DEFAULT
+	return PrecompiledObjectType_PRECOMPILED_OBJECT_TYPE_UNSPECIFIED
 }
 
 // Categories represent the array of messages with sdk and categories at this sdk
@@ -987,17 +990,17 @@ func (x *Categories) GetCategories() []*Categories_Category {
 	return nil
 }
 
-// ListOfExamplesResponse represent the map between sdk and categories for the sdk.
-type GetListOfExamplesResponse struct {
+// GetListOfPrecompiledObjectsResponse represent the map between sdk and categories for the sdk.
+type GetPrecompiledObjectsResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	SdkExamples []*Categories `protobuf:"bytes,1,rep,name=sdk_examples,json=sdkExamples,proto3" json:"sdk_examples,omitempty"`
+	SdkCategories []*Categories `protobuf:"bytes,1,rep,name=sdk_categories,json=sdkCategories,proto3" json:"sdk_categories,omitempty"`
 }
 
-func (x *GetListOfExamplesResponse) Reset() {
-	*x = GetListOfExamplesResponse{}
+func (x *GetPrecompiledObjectsResponse) Reset() {
+	*x = GetPrecompiledObjectsResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_v1_api_proto_msgTypes[15]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1005,13 +1008,13 @@ func (x *GetListOfExamplesResponse) Reset() {
 	}
 }
 
-func (x *GetListOfExamplesResponse) String() string {
+func (x *GetPrecompiledObjectsResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetListOfExamplesResponse) ProtoMessage() {}
+func (*GetPrecompiledObjectsResponse) ProtoMessage() {}
 
-func (x *GetListOfExamplesResponse) ProtoReflect() protoreflect.Message {
+func (x *GetPrecompiledObjectsResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_v1_api_proto_msgTypes[15]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1023,29 +1026,29 @@ func (x *GetListOfExamplesResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetListOfExamplesResponse.ProtoReflect.Descriptor instead.
-func (*GetListOfExamplesResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPrecompiledObjectsResponse.ProtoReflect.Descriptor instead.
+func (*GetPrecompiledObjectsResponse) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{15}
 }
 
-func (x *GetListOfExamplesResponse) GetSdkExamples() []*Categories {
+func (x *GetPrecompiledObjectsResponse) GetSdkCategories() []*Categories {
 	if x != nil {
-		return x.SdkExamples
+		return x.SdkCategories
 	}
 	return nil
 }
 
-// ExampleRequest contains information of the example uuid.
-type GetExampleRequest struct {
+// GetPrecompiledObjectRequest contains information of the PrecompiledObject uuid.
+type GetPrecompiledObjectRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ExampleUuid string `protobuf:"bytes,1,opt,name=example_uuid,json=exampleUuid,proto3" json:"example_uuid,omitempty"`
+	CloudPath string `protobuf:"bytes,1,opt,name=cloud_path,json=cloudPath,proto3" json:"cloud_path,omitempty"`
 }
 
-func (x *GetExampleRequest) Reset() {
-	*x = GetExampleRequest{}
+func (x *GetPrecompiledObjectRequest) Reset() {
+	*x = GetPrecompiledObjectRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_v1_api_proto_msgTypes[16]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1053,13 +1056,13 @@ func (x *GetExampleRequest) Reset() {
 	}
 }
 
-func (x *GetExampleRequest) String() string {
+func (x *GetPrecompiledObjectRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetExampleRequest) ProtoMessage() {}
+func (*GetPrecompiledObjectRequest) ProtoMessage() {}
 
-func (x *GetExampleRequest) ProtoReflect() protoreflect.Message {
+func (x *GetPrecompiledObjectRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_api_v1_api_proto_msgTypes[16]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1071,20 +1074,20 @@ func (x *GetExampleRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetExampleRequest.ProtoReflect.Descriptor instead.
-func (*GetExampleRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPrecompiledObjectRequest.ProtoReflect.Descriptor instead.
+func (*GetPrecompiledObjectRequest) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{16}
 }
 
-func (x *GetExampleRequest) GetExampleUuid() string {
+func (x *GetPrecompiledObjectRequest) GetCloudPath() string {
 	if x != nil {
-		return x.ExampleUuid
+		return x.CloudPath
 	}
 	return ""
 }
 
-// ExampleResponse represents the source code of the example.
-type GetExampleResponse struct {
+// GetPrecompiledObjectResponse represents the source code of the PrecompiledObject.
+type GetPrecompiledObjectCodeResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
@@ -1092,8 +1095,8 @@ type GetExampleResponse struct {
 	Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
 }
 
-func (x *GetExampleResponse) Reset() {
-	*x = GetExampleResponse{}
+func (x *GetPrecompiledObjectCodeResponse) Reset() {
+	*x = GetPrecompiledObjectCodeResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_api_v1_api_proto_msgTypes[17]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1101,13 +1104,13 @@ func (x *GetExampleResponse) Reset() {
 	}
 }
 
-func (x *GetExampleResponse) String() string {
+func (x *GetPrecompiledObjectCodeResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*GetExampleResponse) ProtoMessage() {}
+func (*GetPrecompiledObjectCodeResponse) ProtoMessage() {}
 
-func (x *GetExampleResponse) ProtoReflect() protoreflect.Message {
+func (x *GetPrecompiledObjectCodeResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_api_v1_api_proto_msgTypes[17]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -1119,12 +1122,12 @@ func (x *GetExampleResponse) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use GetExampleResponse.ProtoReflect.Descriptor instead.
-func (*GetExampleResponse) Descriptor() ([]byte, []int) {
+// Deprecated: Use GetPrecompiledObjectCodeResponse.ProtoReflect.Descriptor instead.
+func (*GetPrecompiledObjectCodeResponse) Descriptor() ([]byte, []int) {
 	return file_api_v1_api_proto_rawDescGZIP(), []int{17}
 }
 
-func (x *GetExampleResponse) GetCode() string {
+func (x *GetPrecompiledObjectCodeResponse) GetCode() string {
 	if x != nil {
 		return x.Code
 	}
@@ -1136,8 +1139,8 @@ type Categories_Category struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	CategoryName string     `protobuf:"bytes,1,opt,name=category_name,json=categoryName,proto3" json:"category_name,omitempty"`
-	Examples     []*Example `protobuf:"bytes,2,rep,name=examples,proto3" json:"examples,omitempty"`
+	CategoryName       string               `protobuf:"bytes,1,opt,name=category_name,json=categoryName,proto3" json:"category_name,omitempty"`
+	PrecompiledObjects []*PrecompiledObject `protobuf:"bytes,2,rep,name=precompiled_objects,json=precompiledObjects,proto3" json:"precompiled_objects,omitempty"`
 }
 
 func (x *Categories_Category) Reset() {
@@ -1179,9 +1182,9 @@ func (x *Categories_Category) GetCategoryName() string {
 	return ""
 }
 
-func (x *Categories_Category) GetExamples() []*Example {
+func (x *Categories_Category) GetPrecompiledObjects() []*PrecompiledObject {
 	if x != nil {
-		return x.Examples
+		return x.PrecompiledObjects
 	}
 	return nil
 }
@@ -1235,122 +1238,137 @@ var file_api_v1_api_proto_rawDesc = []byte{
 	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x55, 0x75, 0x69, 0x64,
 	0x22, 0x10, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x55, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x45,
-	0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
-	0x0a, 0x03, 0x73, 0x64, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x64, 0x6b, 0x52, 0x03, 0x73, 0x64, 0x6b, 0x12, 0x1a, 0x0a,
-	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x8b, 0x01, 0x0a, 0x07, 0x45, 0x78,
-	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-	0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b,
-	0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27,
-	0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x61,
-	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x79, 0x70,
-	0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x43, 0x61, 0x74, 0x65,
-	0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x03, 0x73, 0x64, 0x6b, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x64, 0x6b,
-	0x52, 0x03, 0x73, 0x64, 0x6b, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72,
-	0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e,
-	0x76, 0x31, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x43, 0x61,
-	0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69,
-	0x65, 0x73, 0x1a, 0x5c, 0x0a, 0x08, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x23,
-	0x0a, 0x0d, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x4e,
-	0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18,
-	0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45,
-	0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
-	0x22, 0x52, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x45, 0x78, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a,
-	0x0c, 0x73, 0x64, 0x6b, 0x5f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74,
-	0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x0b, 0x73, 0x64, 0x6b, 0x45, 0x78, 0x61, 0x6d,
-	0x70, 0x6c, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70,
-	0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0b, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x22, 0x28, 0x0a, 0x12,
-	0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x2a, 0x52, 0x0a, 0x03, 0x53, 0x64, 0x6b, 0x12, 0x13, 0x0a,
-	0x0f, 0x53, 0x44, 0x4b, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
-	0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x44, 0x4b, 0x5f, 0x4a, 0x41, 0x56, 0x41, 0x10, 0x01,
-	0x12, 0x0a, 0x0a, 0x06, 0x53, 0x44, 0x4b, 0x5f, 0x47, 0x4f, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a,
-	0x53, 0x44, 0x4b, 0x5f, 0x50, 0x59, 0x54, 0x48, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08,
-	0x53, 0x44, 0x4b, 0x5f, 0x53, 0x43, 0x49, 0x4f, 0x10, 0x04, 0x2a, 0xb8, 0x02, 0x0a, 0x06, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
-	0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a,
-	0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49,
-	0x4e, 0x47, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56,
-	0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10,
-	0x02, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x45, 0x50,
-	0x41, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x54, 0x41, 0x54, 0x55,
-	0x53, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x52,
-	0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
-	0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x53,
-	0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x52,
-	0x52, 0x4f, 0x52, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
-	0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x53,
-	0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x08,
-	0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x45,
-	0x52, 0x52, 0x4f, 0x52, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
-	0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54,
-	0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0b,
-	0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45,
-	0x4c, 0x45, 0x44, 0x10, 0x0c, 0x2a, 0x5a, 0x0a, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
-	0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x5f,
-	0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x15,
-	0x0a, 0x11, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4b,
-	0x41, 0x54, 0x41, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45,
-	0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x10,
-	0x02, 0x32, 0xa6, 0x05, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x79, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x43, 0x6f,
-	0x64, 0x65, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x43,
-	0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69,
-	0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63,
-	0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
-	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x47,
-	0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x70,
-	0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
-	0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e,
-	0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47,
-	0x65, 0x74, 0x52, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75,
-	0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55,
-	0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70,
-	0x75, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43,
-	0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12,
-	0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
-	0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58,
-	0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x45, 0x78, 0x61, 0x6d, 0x70,
-	0x6c, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
-	0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47,
-	0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45,
-	0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
-	0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78,
-	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a,
-	0x10, 0x47, 0x65, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75,
-	0x74, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78,
-	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61,
+	0x73, 0x65, 0x22, 0x59, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70,
+	0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x73, 0x64, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x64, 0x6b, 0x52, 0x03, 0x73, 0x64,
+	0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x22, 0x9b, 0x01,
+	0x0a, 0x11, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a,
+	0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x70, 0x61, 0x74,
+	0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x61,
+	0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x31, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
+	0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63,
+	0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe5, 0x01, 0x0a, 0x0a,
+	0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x03, 0x73, 0x64,
+	0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x2e, 0x53, 0x64, 0x6b, 0x52, 0x03, 0x73, 0x64, 0x6b, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x61, 0x74,
+	0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65,
+	0x73, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65,
+	0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x7b, 0x0a, 0x08, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f,
+	0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x74, 0x65, 0x67,
+	0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x63, 0x6f,
+	0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x02,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72,
+	0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52,
+	0x12, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
+	0x63, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d,
+	0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0e, 0x73, 0x64, 0x6b, 0x5f, 0x63, 0x61, 0x74, 0x65,
+	0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73,
+	0x52, 0x0d, 0x73, 0x64, 0x6b, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22,
+	0x3c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+	0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
+	0x0a, 0x0a, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x61, 0x74, 0x68, 0x22, 0x36, 0x0a,
+	0x20, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f,
+	0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x63, 0x6f, 0x64, 0x65, 0x2a, 0x52, 0x0a, 0x03, 0x53, 0x64, 0x6b, 0x12, 0x13, 0x0a, 0x0f,
+	0x53, 0x44, 0x4b, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+	0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x44, 0x4b, 0x5f, 0x4a, 0x41, 0x56, 0x41, 0x10, 0x01, 0x12,
+	0x0a, 0x0a, 0x06, 0x53, 0x44, 0x4b, 0x5f, 0x47, 0x4f, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x53,
+	0x44, 0x4b, 0x5f, 0x50, 0x59, 0x54, 0x48, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x53,
+	0x44, 0x4b, 0x5f, 0x53, 0x43, 0x49, 0x4f, 0x10, 0x04, 0x2a, 0xb8, 0x02, 0x0a, 0x06, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55,
+	0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11,
+	0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4e,
+	0x47, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x41,
+	0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02,
+	0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x45, 0x50, 0x41,
+	0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
+	0x5f, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x45, 0x52, 0x52,
+	0x4f, 0x52, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43,
+	0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x54,
+	0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x52, 0x52,
+	0x4f, 0x52, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45,
+	0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54,
+	0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, 0x10, 0x08, 0x12,
+	0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x45, 0x52,
+	0x52, 0x4f, 0x52, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+	0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x0a, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55,
+	0x53, 0x5f, 0x52, 0x55, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x0b, 0x12,
+	0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c,
+	0x45, 0x44, 0x10, 0x0c, 0x2a, 0xae, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70,
+	0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x27,
+	0x0a, 0x23, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, 0x42,
+	0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+	0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x52, 0x45, 0x43, 0x4f,
+	0x4d, 0x50, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59,
+	0x50, 0x45, 0x5f, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c,
+	0x50, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, 0x42, 0x4a, 0x45,
+	0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4b, 0x41, 0x54, 0x41, 0x10, 0x02, 0x12, 0x25,
+	0x0a, 0x21, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x4f, 0x42,
+	0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x54,
+	0x45, 0x53, 0x54, 0x10, 0x03, 0x32, 0xec, 0x05, 0x0a, 0x11, 0x50, 0x6c, 0x61, 0x79, 0x67, 0x72,
+	0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x52,
+	0x75, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
+	0x52, 0x75, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17,
+	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
+	0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63,
+	0x6b, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x49, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12,
+	0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f,
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61,
 	0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70,
-	0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x62, 0x65,
-	0x61, 0x6d, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x6c,
-	0x61, 0x79, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
-	0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3b, 0x70, 0x6c, 0x61, 0x79, 0x67, 0x72,
-	0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x47, 0x65,
+	0x74, 0x52, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47,
+	0x65, 0x74, 0x52, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+	0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
+	0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
+	0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x43, 0x61, 0x6e,
+	0x63, 0x65, 0x6c, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e,
+	0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69,
+	0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70,
+	0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70,
+	0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69,
+	0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x25, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72,
+	0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50,
+	0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+	0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
+	0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
+	0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+	0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x63, 0x6f, 0x6d,
+	0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75,
+	0x74, 0x12, 0x23, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72,
+	0x65, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
+	0x47, 0x65, 0x74, 0x52, 0x75, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x42, 0x38, 0x5a, 0x36, 0x62, 0x65, 0x61, 0x6d, 0x2e, 0x61, 0x70, 0x61,
+	0x63, 0x68, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x6c, 0x61, 0x79, 0x67, 0x72, 0x6f, 0x75,
+	0x6e, 0x64, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x6e, 0x61, 0x6c, 0x3b, 0x70, 0x6c, 0x61, 0x79, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1368,57 +1386,57 @@ func file_api_v1_api_proto_rawDescGZIP() []byte {
 var file_api_v1_api_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
 var file_api_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
 var file_api_v1_api_proto_goTypes = []interface{}{
-	(Sdk)(0),                          // 0: api.v1.Sdk
-	(Status)(0),                       // 1: api.v1.Status
-	(ExampleType)(0),                  // 2: api.v1.ExampleType
-	(*RunCodeRequest)(nil),            // 3: api.v1.RunCodeRequest
-	(*RunCodeResponse)(nil),           // 4: api.v1.RunCodeResponse
-	(*CheckStatusRequest)(nil),        // 5: api.v1.CheckStatusRequest
-	(*CheckStatusResponse)(nil),       // 6: api.v1.CheckStatusResponse
-	(*GetCompileOutputRequest)(nil),   // 7: api.v1.GetCompileOutputRequest
-	(*GetCompileOutputResponse)(nil),  // 8: api.v1.GetCompileOutputResponse
-	(*GetRunOutputRequest)(nil),       // 9: api.v1.GetRunOutputRequest
-	(*GetRunOutputResponse)(nil),      // 10: api.v1.GetRunOutputResponse
-	(*GetRunErrorRequest)(nil),        // 11: api.v1.GetRunErrorRequest
-	(*GetRunErrorResponse)(nil),       // 12: api.v1.GetRunErrorResponse
-	(*CancelRequest)(nil),             // 13: api.v1.CancelRequest
-	(*CancelResponse)(nil),            // 14: api.v1.CancelResponse
-	(*GetListOfExamplesRequest)(nil),  // 15: api.v1.GetListOfExamplesRequest
-	(*Example)(nil),                   // 16: api.v1.Example
-	(*Categories)(nil),                // 17: api.v1.Categories
-	(*GetListOfExamplesResponse)(nil), // 18: api.v1.GetListOfExamplesResponse
-	(*GetExampleRequest)(nil),         // 19: api.v1.GetExampleRequest
-	(*GetExampleResponse)(nil),        // 20: api.v1.GetExampleResponse
-	(*Categories_Category)(nil),       // 21: api.v1.Categories.Category
+	(Sdk)(0),                                 // 0: api.v1.Sdk
+	(Status)(0),                              // 1: api.v1.Status
+	(PrecompiledObjectType)(0),               // 2: api.v1.PrecompiledObjectType
+	(*RunCodeRequest)(nil),                   // 3: api.v1.RunCodeRequest
+	(*RunCodeResponse)(nil),                  // 4: api.v1.RunCodeResponse
+	(*CheckStatusRequest)(nil),               // 5: api.v1.CheckStatusRequest
+	(*CheckStatusResponse)(nil),              // 6: api.v1.CheckStatusResponse
+	(*GetCompileOutputRequest)(nil),          // 7: api.v1.GetCompileOutputRequest
+	(*GetCompileOutputResponse)(nil),         // 8: api.v1.GetCompileOutputResponse
+	(*GetRunOutputRequest)(nil),              // 9: api.v1.GetRunOutputRequest
+	(*GetRunOutputResponse)(nil),             // 10: api.v1.GetRunOutputResponse
+	(*GetRunErrorRequest)(nil),               // 11: api.v1.GetRunErrorRequest
+	(*GetRunErrorResponse)(nil),              // 12: api.v1.GetRunErrorResponse
+	(*CancelRequest)(nil),                    // 13: api.v1.CancelRequest
+	(*CancelResponse)(nil),                   // 14: api.v1.CancelResponse
+	(*GetPrecompiledObjectsRequest)(nil),     // 15: api.v1.GetPrecompiledObjectsRequest
+	(*PrecompiledObject)(nil),                // 16: api.v1.PrecompiledObject
+	(*Categories)(nil),                       // 17: api.v1.Categories
+	(*GetPrecompiledObjectsResponse)(nil),    // 18: api.v1.GetPrecompiledObjectsResponse
+	(*GetPrecompiledObjectRequest)(nil),      // 19: api.v1.GetPrecompiledObjectRequest
+	(*GetPrecompiledObjectCodeResponse)(nil), // 20: api.v1.GetPrecompiledObjectCodeResponse
+	(*Categories_Category)(nil),              // 21: api.v1.Categories.Category
 }
 var file_api_v1_api_proto_depIdxs = []int32{
 	0,  // 0: api.v1.RunCodeRequest.sdk:type_name -> api.v1.Sdk
 	1,  // 1: api.v1.CheckStatusResponse.status:type_name -> api.v1.Status
 	1,  // 2: api.v1.GetCompileOutputResponse.compilation_status:type_name -> api.v1.Status
-	0,  // 3: api.v1.GetListOfExamplesRequest.sdk:type_name -> api.v1.Sdk
-	2,  // 4: api.v1.Example.type:type_name -> api.v1.ExampleType
+	0,  // 3: api.v1.GetPrecompiledObjectsRequest.sdk:type_name -> api.v1.Sdk
+	2,  // 4: api.v1.PrecompiledObject.type:type_name -> api.v1.PrecompiledObjectType
 	0,  // 5: api.v1.Categories.sdk:type_name -> api.v1.Sdk
 	21, // 6: api.v1.Categories.categories:type_name -> api.v1.Categories.Category
-	17, // 7: api.v1.GetListOfExamplesResponse.sdk_examples:type_name -> api.v1.Categories
-	16, // 8: api.v1.Categories.Category.examples:type_name -> api.v1.Example
+	17, // 7: api.v1.GetPrecompiledObjectsResponse.sdk_categories:type_name -> api.v1.Categories
+	16, // 8: api.v1.Categories.Category.precompiled_objects:type_name -> api.v1.PrecompiledObject
 	3,  // 9: api.v1.PlaygroundService.RunCode:input_type -> api.v1.RunCodeRequest
 	5,  // 10: api.v1.PlaygroundService.CheckStatus:input_type -> api.v1.CheckStatusRequest
 	9,  // 11: api.v1.PlaygroundService.GetRunOutput:input_type -> api.v1.GetRunOutputRequest
 	11, // 12: api.v1.PlaygroundService.GetRunError:input_type -> api.v1.GetRunErrorRequest
 	7,  // 13: api.v1.PlaygroundService.GetCompileOutput:input_type -> api.v1.GetCompileOutputRequest
 	13, // 14: api.v1.PlaygroundService.Cancel:input_type -> api.v1.CancelRequest
-	15, // 15: api.v1.PlaygroundService.GetListOfExamples:input_type -> api.v1.GetListOfExamplesRequest
-	19, // 16: api.v1.PlaygroundService.GetExample:input_type -> api.v1.GetExampleRequest
-	19, // 17: api.v1.PlaygroundService.GetExampleOutput:input_type -> api.v1.GetExampleRequest
+	15, // 15: api.v1.PlaygroundService.GetPrecompiledObjects:input_type -> api.v1.GetPrecompiledObjectsRequest
+	19, // 16: api.v1.PlaygroundService.GetPrecompiledObjectCode:input_type -> api.v1.GetPrecompiledObjectRequest
+	19, // 17: api.v1.PlaygroundService.GetPrecompiledObjectOutput:input_type -> api.v1.GetPrecompiledObjectRequest
 	4,  // 18: api.v1.PlaygroundService.RunCode:output_type -> api.v1.RunCodeResponse
 	6,  // 19: api.v1.PlaygroundService.CheckStatus:output_type -> api.v1.CheckStatusResponse
 	10, // 20: api.v1.PlaygroundService.GetRunOutput:output_type -> api.v1.GetRunOutputResponse
 	12, // 21: api.v1.PlaygroundService.GetRunError:output_type -> api.v1.GetRunErrorResponse
 	8,  // 22: api.v1.PlaygroundService.GetCompileOutput:output_type -> api.v1.GetCompileOutputResponse
 	14, // 23: api.v1.PlaygroundService.Cancel:output_type -> api.v1.CancelResponse
-	18, // 24: api.v1.PlaygroundService.GetListOfExamples:output_type -> api.v1.GetListOfExamplesResponse
-	20, // 25: api.v1.PlaygroundService.GetExample:output_type -> api.v1.GetExampleResponse
-	10, // 26: api.v1.PlaygroundService.GetExampleOutput:output_type -> api.v1.GetRunOutputResponse
+	18, // 24: api.v1.PlaygroundService.GetPrecompiledObjects:output_type -> api.v1.GetPrecompiledObjectsResponse
+	20, // 25: api.v1.PlaygroundService.GetPrecompiledObjectCode:output_type -> api.v1.GetPrecompiledObjectCodeResponse
+	10, // 26: api.v1.PlaygroundService.GetPrecompiledObjectOutput:output_type -> api.v1.GetRunOutputResponse
 	18, // [18:27] is the sub-list for method output_type
 	9,  // [9:18] is the sub-list for method input_type
 	9,  // [9:9] is the sub-list for extension type_name
@@ -1577,7 +1595,7 @@ func file_api_v1_api_proto_init() {
 			}
 		}
 		file_api_v1_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetListOfExamplesRequest); i {
+			switch v := v.(*GetPrecompiledObjectsRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1589,7 +1607,7 @@ func file_api_v1_api_proto_init() {
 			}
 		}
 		file_api_v1_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Example); i {
+			switch v := v.(*PrecompiledObject); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1613,7 +1631,7 @@ func file_api_v1_api_proto_init() {
 			}
 		}
 		file_api_v1_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetListOfExamplesResponse); i {
+			switch v := v.(*GetPrecompiledObjectsResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1625,7 +1643,7 @@ func file_api_v1_api_proto_init() {
 			}
 		}
 		file_api_v1_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetExampleRequest); i {
+			switch v := v.(*GetPrecompiledObjectRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1637,7 +1655,7 @@ func file_api_v1_api_proto_init() {
 			}
 		}
 		file_api_v1_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GetExampleResponse); i {
+			switch v := v.(*GetPrecompiledObjectCodeResponse); i {
 			case 0:
 				return &v.state
 			case 1:
diff --git a/playground/backend/internal/api/v1/api_grpc.pb.go b/playground/backend/internal/api/v1/api_grpc.pb.go
index c708d89..93b5dd4 100644
--- a/playground/backend/internal/api/v1/api_grpc.pb.go
+++ b/playground/backend/internal/api/v1/api_grpc.pb.go
@@ -47,12 +47,12 @@ type PlaygroundServiceClient interface {
 	GetCompileOutput(ctx context.Context, in *GetCompileOutputRequest, opts ...grpc.CallOption) (*GetCompileOutputResponse, error)
 	// Cancel code processing
 	Cancel(ctx context.Context, in *CancelRequest, opts ...grpc.CallOption) (*CancelResponse, error)
-	// Get the list of precompiled examples.
-	GetListOfExamples(ctx context.Context, in *GetListOfExamplesRequest, opts ...grpc.CallOption) (*GetListOfExamplesResponse, error)
-	// Get the code of an example.
-	GetExample(ctx context.Context, in *GetExampleRequest, opts ...grpc.CallOption) (*GetExampleResponse, error)
-	// Get the precompiled details of an example.
-	GetExampleOutput(ctx context.Context, in *GetExampleRequest, opts ...grpc.CallOption) (*GetRunOutputResponse, error)
+	// Get all precompiled objects from the cloud storage.
+	GetPrecompiledObjects(ctx context.Context, in *GetPrecompiledObjectsRequest, opts ...grpc.CallOption) (*GetPrecompiledObjectsResponse, error)
+	// Get the code of an PrecompiledObject.
+	GetPrecompiledObjectCode(ctx context.Context, in *GetPrecompiledObjectRequest, opts ...grpc.CallOption) (*GetPrecompiledObjectCodeResponse, error)
+	// Get the precompiled details of an PrecompiledObject.
+	GetPrecompiledObjectOutput(ctx context.Context, in *GetPrecompiledObjectRequest, opts ...grpc.CallOption) (*GetRunOutputResponse, error)
 }
 
 type playgroundServiceClient struct {
@@ -117,27 +117,27 @@ func (c *playgroundServiceClient) Cancel(ctx context.Context, in *CancelRequest,
 	return out, nil
 }
 
-func (c *playgroundServiceClient) GetListOfExamples(ctx context.Context, in *GetListOfExamplesRequest, opts ...grpc.CallOption) (*GetListOfExamplesResponse, error) {
-	out := new(GetListOfExamplesResponse)
-	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetListOfExamples", in, out, opts...)
+func (c *playgroundServiceClient) GetPrecompiledObjects(ctx context.Context, in *GetPrecompiledObjectsRequest, opts ...grpc.CallOption) (*GetPrecompiledObjectsResponse, error) {
+	out := new(GetPrecompiledObjectsResponse)
+	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetPrecompiledObjects", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
 	return out, nil
 }
 
-func (c *playgroundServiceClient) GetExample(ctx context.Context, in *GetExampleRequest, opts ...grpc.CallOption) (*GetExampleResponse, error) {
-	out := new(GetExampleResponse)
-	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetExample", in, out, opts...)
+func (c *playgroundServiceClient) GetPrecompiledObjectCode(ctx context.Context, in *GetPrecompiledObjectRequest, opts ...grpc.CallOption) (*GetPrecompiledObjectCodeResponse, error) {
+	out := new(GetPrecompiledObjectCodeResponse)
+	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetPrecompiledObjectCode", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
 	return out, nil
 }
 
-func (c *playgroundServiceClient) GetExampleOutput(ctx context.Context, in *GetExampleRequest, opts ...grpc.CallOption) (*GetRunOutputResponse, error) {
+func (c *playgroundServiceClient) GetPrecompiledObjectOutput(ctx context.Context, in *GetPrecompiledObjectRequest, opts ...grpc.CallOption) (*GetRunOutputResponse, error) {
 	out := new(GetRunOutputResponse)
-	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetExampleOutput", in, out, opts...)
+	err := c.cc.Invoke(ctx, "/api.v1.PlaygroundService/GetPrecompiledObjectOutput", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -160,12 +160,12 @@ type PlaygroundServiceServer interface {
 	GetCompileOutput(context.Context, *GetCompileOutputRequest) (*GetCompileOutputResponse, error)
 	// Cancel code processing
 	Cancel(context.Context, *CancelRequest) (*CancelResponse, error)
-	// Get the list of precompiled examples.
-	GetListOfExamples(context.Context, *GetListOfExamplesRequest) (*GetListOfExamplesResponse, error)
-	// Get the code of an example.
-	GetExample(context.Context, *GetExampleRequest) (*GetExampleResponse, error)
-	// Get the precompiled details of an example.
-	GetExampleOutput(context.Context, *GetExampleRequest) (*GetRunOutputResponse, error)
+	// Get all precompiled objects from the cloud storage.
+	GetPrecompiledObjects(context.Context, *GetPrecompiledObjectsRequest) (*GetPrecompiledObjectsResponse, error)
+	// Get the code of an PrecompiledObject.
+	GetPrecompiledObjectCode(context.Context, *GetPrecompiledObjectRequest) (*GetPrecompiledObjectCodeResponse, error)
+	// Get the precompiled details of an PrecompiledObject.
+	GetPrecompiledObjectOutput(context.Context, *GetPrecompiledObjectRequest) (*GetRunOutputResponse, error)
 }
 
 // UnimplementedPlaygroundServiceServer should be embedded to have forward compatible implementations.
@@ -190,14 +190,14 @@ func (UnimplementedPlaygroundServiceServer) GetCompileOutput(context.Context, *G
 func (UnimplementedPlaygroundServiceServer) Cancel(context.Context, *CancelRequest) (*CancelResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Cancel not implemented")
 }
-func (UnimplementedPlaygroundServiceServer) GetListOfExamples(context.Context, *GetListOfExamplesRequest) (*GetListOfExamplesResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetListOfExamples not implemented")
+func (UnimplementedPlaygroundServiceServer) GetPrecompiledObjects(context.Context, *GetPrecompiledObjectsRequest) (*GetPrecompiledObjectsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetPrecompiledObjects not implemented")
 }
-func (UnimplementedPlaygroundServiceServer) GetExample(context.Context, *GetExampleRequest) (*GetExampleResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetExample not implemented")
+func (UnimplementedPlaygroundServiceServer) GetPrecompiledObjectCode(context.Context, *GetPrecompiledObjectRequest) (*GetPrecompiledObjectCodeResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetPrecompiledObjectCode not implemented")
 }
-func (UnimplementedPlaygroundServiceServer) GetExampleOutput(context.Context, *GetExampleRequest) (*GetRunOutputResponse, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetExampleOutput not implemented")
+func (UnimplementedPlaygroundServiceServer) GetPrecompiledObjectOutput(context.Context, *GetPrecompiledObjectRequest) (*GetRunOutputResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetPrecompiledObjectOutput not implemented")
 }
 
 // UnsafePlaygroundServiceServer may be embedded to opt out of forward compatibility for this service.
@@ -319,56 +319,56 @@ func _PlaygroundService_Cancel_Handler(srv interface{}, ctx context.Context, dec
 	return interceptor(ctx, in, info, handler)
 }
 
-func _PlaygroundService_GetListOfExamples_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GetListOfExamplesRequest)
+func _PlaygroundService_GetPrecompiledObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetPrecompiledObjectsRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(PlaygroundServiceServer).GetListOfExamples(ctx, in)
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjects(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/api.v1.PlaygroundService/GetListOfExamples",
+		FullMethod: "/api.v1.PlaygroundService/GetPrecompiledObjects",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(PlaygroundServiceServer).GetListOfExamples(ctx, req.(*GetListOfExamplesRequest))
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjects(ctx, req.(*GetPrecompiledObjectsRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
 
-func _PlaygroundService_GetExample_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GetExampleRequest)
+func _PlaygroundService_GetPrecompiledObjectCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetPrecompiledObjectRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(PlaygroundServiceServer).GetExample(ctx, in)
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjectCode(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/api.v1.PlaygroundService/GetExample",
+		FullMethod: "/api.v1.PlaygroundService/GetPrecompiledObjectCode",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(PlaygroundServiceServer).GetExample(ctx, req.(*GetExampleRequest))
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjectCode(ctx, req.(*GetPrecompiledObjectRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
 
-func _PlaygroundService_GetExampleOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GetExampleRequest)
+func _PlaygroundService_GetPrecompiledObjectOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetPrecompiledObjectRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(PlaygroundServiceServer).GetExampleOutput(ctx, in)
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjectOutput(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: "/api.v1.PlaygroundService/GetExampleOutput",
+		FullMethod: "/api.v1.PlaygroundService/GetPrecompiledObjectOutput",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(PlaygroundServiceServer).GetExampleOutput(ctx, req.(*GetExampleRequest))
+		return srv.(PlaygroundServiceServer).GetPrecompiledObjectOutput(ctx, req.(*GetPrecompiledObjectRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
@@ -405,16 +405,16 @@ var PlaygroundService_ServiceDesc = grpc.ServiceDesc{
 			Handler:    _PlaygroundService_Cancel_Handler,
 		},
 		{
-			MethodName: "GetListOfExamples",
-			Handler:    _PlaygroundService_GetListOfExamples_Handler,
+			MethodName: "GetPrecompiledObjects",
+			Handler:    _PlaygroundService_GetPrecompiledObjects_Handler,
 		},
 		{
-			MethodName: "GetExample",
-			Handler:    _PlaygroundService_GetExample_Handler,
+			MethodName: "GetPrecompiledObjectCode",
+			Handler:    _PlaygroundService_GetPrecompiledObjectCode_Handler,
 		},
 		{
-			MethodName: "GetExampleOutput",
-			Handler:    _PlaygroundService_GetExampleOutput_Handler,
+			MethodName: "GetPrecompiledObjectOutput",
+			Handler:    _PlaygroundService_GetPrecompiledObjectOutput_Handler,
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
diff --git a/playground/backend/internal/cloud_bucket/precompiled_objects.go b/playground/backend/internal/cloud_bucket/precompiled_objects.go
new file mode 100644
index 0000000..87b353d
--- /dev/null
+++ b/playground/backend/internal/cloud_bucket/precompiled_objects.go
@@ -0,0 +1,278 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cloud_bucket
+
+import (
+	pb "beam.apache.org/playground/backend/internal/api/v1"
+	"beam.apache.org/playground/backend/internal/logger"
+	"cloud.google.com/go/storage"
+	"context"
+	"encoding/json"
+	"fmt"
+	"google.golang.org/api/iterator"
+	"google.golang.org/api/option"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+const (
+	BucketName       = "playground-precompiled-objects"
+	OutputExtension  = "output"
+	MetaInfoName     = "meta.info"
+	Timeout          = time.Second * 10
+	javaExtension    = "java"
+	goExtension      = "go"
+	pyExtension      = "py"
+	scioExtension    = "scala"
+	separatorsNumber = 2
+)
+
+type ObjectInfo struct {
+	Name        string
+	CloudPath   string
+	Description string                   `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	Type        pb.PrecompiledObjectType `protobuf:"varint,4,opt,name=type,proto3,enum=api.v1.PrecompiledObjectType" json:"type,omitempty"`
+	Categories  []string                 `json:"categories,omitempty"`
+}
+
+type PrecompiledObjects []ObjectInfo
+type CategoryToPrecompiledObjects map[string]PrecompiledObjects
+type SdkToCategories map[string]CategoryToPrecompiledObjects
+
+// CloudStorage represents working tools for getting compiled and
+// run beam examples from Google Cloud Storage. It is required that
+// the bucket where examples are stored would be public,
+// and it has a specific structure of files, namely:
+// SDK_JAVA/
+// --------MinimalWordCount/
+// ----------- MinimalWordCount.java
+// ----------- MinimalWordCount.output
+// ----------- meta.info
+// --------JoinExamples/
+// ----------- JoinExamples.java
+// ----------- JoinExamples.output
+// ----------- meta.info
+// ----  ...
+// SDK_GO/
+// --------MinimalWordCount/
+// ----------- MinimalWordCount.go
+// ----------- MinimalWordCount.output
+// ----------- meta.info
+// --------PingPong/
+// ----  ...
+// ...
+// meta.info is a json file that has the following fields:
+// {
+//	"description": "Description of an example",
+//	"type": 1, ## 1 - Example, 2 - Kata, 3 - Unit-test
+//	"categories": ["Common", "IO"]
+// }
+//
+type CloudStorage struct {
+}
+
+func New() *CloudStorage {
+	return &CloudStorage{}
+}
+
+// GetPrecompiledObject returns the source code of the example
+func (cd *CloudStorage) GetPrecompiledObject(ctx context.Context, precompiledObjectPath string) (*string, error) {
+	extension, err := getFileExtensionBySdk(precompiledObjectPath)
+	if err != nil {
+		return nil, err
+	}
+	data, err := cd.getFileFromBucket(ctx, precompiledObjectPath, extension)
+	if err != nil {
+		return nil, err
+	}
+	result := string(data)
+	return &result, nil
+}
+
+// GetPrecompiledObjectOutput returns the run output of the example
+func (cd *CloudStorage) GetPrecompiledObjectOutput(ctx context.Context, precompiledObjectPath string) (*string, error) {
+	data, err := cd.getFileFromBucket(ctx, precompiledObjectPath, OutputExtension)
+	if err != nil {
+		return nil, err
+	}
+	result := string(data)
+	return &result, nil
+}
+
+// GetPrecompiledObjects returns stored at the cloud storage bucket precompiled objects for the target category
+func (cd *CloudStorage) GetPrecompiledObjects(ctx context.Context, targetSdk pb.Sdk, targetCategory string) (*SdkToCategories, error) {
+	client, err := storage.NewClient(ctx, option.WithoutAuthentication())
+	if err != nil {
+		return nil, fmt.Errorf("storage.NewClient: %v", err)
+	}
+	defer client.Close()
+
+	ctx, cancel := context.WithTimeout(ctx, Timeout)
+	defer cancel()
+
+	precompiledObjects := make(SdkToCategories, 0)
+	bucket := client.Bucket(BucketName)
+
+	dirs, err := cd.getPrecompiledObjectsDirs(ctx, targetSdk, bucket)
+	if err != nil {
+		return nil, err
+	}
+	for objectDir := range dirs {
+		infoPath := filepath.Join(objectDir, MetaInfoName) // helping file with information about this object
+		rc, err := bucket.Object(infoPath).NewReader(ctx)
+		if err != nil {
+			logger.Errorf("Object(%q).NewReader: %v", infoPath, err.Error())
+			continue
+		}
+		data, err := ioutil.ReadAll(rc)
+		if err != nil {
+			logger.Errorf("ioutil.ReadAll: %v", err.Error())
+			continue
+		}
+		precompiledObject := ObjectInfo{}
+		err = json.Unmarshal(data, &precompiledObject)
+		if err != nil {
+			logger.Errorf("json.Unmarshal: %v", err.Error())
+			continue
+		}
+		for _, objectCategory := range precompiledObject.Categories {
+			if targetCategory == "" || targetCategory == objectCategory { //take only requested categories
+				appendPrecompiledObject(precompiledObject, &precompiledObjects, objectDir, objectCategory)
+			}
+		}
+		rc.Close()
+	}
+	return &precompiledObjects, nil
+}
+
+// getPrecompiledObjectsDirs finds directories with precompiled objects
+// Since there is no notion of directory at cloud storage, then
+// to avoid duplicates of a base path (directory) need to store it in a set/map.
+func (cd *CloudStorage) getPrecompiledObjectsDirs(ctx context.Context, targetSdk pb.Sdk, bucket *storage.BucketHandle) (map[string]bool, error) {
+	prefix := targetSdk.String()
+	if targetSdk == pb.Sdk_SDK_UNSPECIFIED {
+		prefix = ""
+	}
+	it := bucket.Objects(ctx, &storage.Query{
+		Prefix: prefix,
+	})
+	objectDirs := make(map[string]bool, 0)
+	for {
+		attrs, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			return nil, fmt.Errorf("Bucket(%q).Objects: %v", BucketName, err)
+		}
+		path := attrs.Name
+		if isPathToPrecompiledObjectFile(path) {
+			objectDirs[filepath.Dir(path)] = true //save base path (directory) of a file
+		}
+	}
+	return objectDirs, nil
+}
+
+// appendPrecompiledObject add precompiled object to the common structure of precompiled objects
+func appendPrecompiledObject(objectInfo ObjectInfo, sdkToCategories *SdkToCategories, pathToObject string, categoryName string) {
+	sdkName := getSdkName(pathToObject)
+	categoryToPrecompiledObjects, ok := (*sdkToCategories)[sdkName]
+	if !ok {
+		(*sdkToCategories)[sdkName] = make(CategoryToPrecompiledObjects, 0)
+		categoryToPrecompiledObjects = (*sdkToCategories)[sdkName]
+	}
+	objects, ok := categoryToPrecompiledObjects[categoryName]
+	if !ok {
+		categoryToPrecompiledObjects[categoryName] = make(PrecompiledObjects, 0)
+		objects = categoryToPrecompiledObjects[categoryName]
+	}
+	objectInfo.CloudPath = pathToObject
+	objectInfo.Name = filepath.Base(pathToObject)
+	categoryToPrecompiledObjects[categoryName] = append(objects, objectInfo)
+}
+
+// getFileFromBucket receives the file from the bucket by its name
+func (cd *CloudStorage) getFileFromBucket(ctx context.Context, pathToObject string, extension string) ([]byte, error) {
+	client, err := storage.NewClient(ctx, option.WithoutAuthentication())
+	if err != nil {
+		return nil, fmt.Errorf("storage.NewClient: %v", err)
+	}
+	defer client.Close()
+
+	ctx, cancel := context.WithTimeout(ctx, Timeout)
+	defer cancel()
+
+	bucket := client.Bucket(BucketName)
+
+	filePath := getFullFilePath(pathToObject, extension)
+	rc, err := bucket.Object(filePath).NewReader(ctx)
+	if err != nil {
+		return nil, fmt.Errorf("Object(%q).NewReader: %v", filePath, err)
+	}
+	defer rc.Close()
+
+	data, err := ioutil.ReadAll(rc)
+	if err != nil {
+		return nil, fmt.Errorf("ioutil.ReadAll: %v", err)
+	}
+	return data, nil
+}
+
+// getFileExtensionBySdk get extension of the file with code by the sdk name
+func getFileExtensionBySdk(precompiledObjectPath string) (string, error) {
+	sdk := strings.Split(precompiledObjectPath, string(os.PathSeparator))[0]
+	var extension string
+	switch sdk {
+	case pb.Sdk_SDK_JAVA.String():
+		extension = javaExtension
+	case pb.Sdk_SDK_PYTHON.String():
+		extension = pyExtension
+	case pb.Sdk_SDK_GO.String():
+		extension = goExtension
+	case pb.Sdk_SDK_SCIO.String():
+		extension = scioExtension
+	default:
+		return "", fmt.Errorf("")
+	}
+	return extension, nil
+}
+
+// getFullFilePath get full path to the precompiled object file
+func getFullFilePath(objectDir string, extension string) string {
+	precompiledObjectName := filepath.Base(objectDir) //the base of the object's directory matches the name of the file
+	fileName := strings.Join([]string{precompiledObjectName, extension}, ".")
+	filePath := filepath.Join(objectDir, fileName)
+	return filePath
+}
+
+// isPathToPrecompiledObjectFile is it a path where precompiled object is stored (i.e. SDK/ObjectName/ObjectCode.sdkExtension)
+func isPathToPrecompiledObjectFile(path string) bool {
+	return strings.Count(path, string(os.PathSeparator)) == separatorsNumber && !isDir(path)
+}
+
+// isDir checks whether the path imitates directory
+func isDir(path string) bool {
+	return path[len(path)-1] == os.PathSeparator
+}
+
+// getSdkName gets category and sdk from the filepath
+func getSdkName(path string) string {
+	sdkName := strings.Split(path, string(os.PathSeparator))[0] // the path of the form "sdkName/example/", where the first part is sdkName
+	return sdkName
+}
diff --git a/playground/backend/internal/cloud_bucket/precompiled_objects_test.go b/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
new file mode 100644
index 0000000..b5950fa
--- /dev/null
+++ b/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
@@ -0,0 +1,222 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cloud_bucket
+
+import (
+	"reflect"
+	"testing"
+)
+
+func Test_getFullFilePath(t *testing.T) {
+	type args struct {
+		examplePath string
+		extension   string
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			// Try to get the full path to the code of the precompiled example
+			// by the path to its directory on Cloud Storage:
+			// (SDK_JAVA/HelloWorld, java) -> SDK_JAVA/HelloWorld/HelloWorld.java
+			name: "Test getFullFilePath()",
+			args: args{
+				examplePath: "SDK_JAVA/HelloWorld",
+				extension:   "java",
+			},
+			want: "SDK_JAVA/HelloWorld/HelloWorld.java",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := getFullFilePath(tt.args.examplePath, tt.args.extension); got != tt.want {
+				t.Errorf("getFullFilePath() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_getSdkName(t *testing.T) {
+	type args struct {
+		path string
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			// Try to get the name of the SDK from the path
+			name: "Test getSdkName",
+			args: args{path: "SDK_JAVA/HelloWorld"},
+			want: "SDK_JAVA",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := getSdkName(tt.args.path); got != tt.want {
+				t.Errorf("getSdkName() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_isDir(t *testing.T) {
+	type args struct {
+		path string
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		{
+			name: "Test isDir if it is a directory",
+			args: args{path: "SDK_JAVA/HelloWorld/"},
+			want: true,
+		},
+		{
+			name: "Test isDir if it is a file",
+			args: args{path: "SDK_JAVA/HelloWorld/HelloWorld.java"},
+			want: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := isDir(tt.args.path); got != tt.want {
+				t.Errorf("isDir() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_isPathToPrecompiledObjectFile(t *testing.T) {
+	type args struct {
+		path string
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		{
+			name: "Test if path is valid",
+			args: args{path: "SDK_JAVA/HelloWorld/HelloWorld.java"},
+			want: true,
+		},
+		{
+			name: "Test if path is not valid",
+			args: args{path: "SDK_JAVA/HelloWorld/"},
+			want: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := isPathToPrecompiledObjectFile(tt.args.path); got != tt.want {
+				t.Errorf("isPathToPrecompiledObjectFile() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_appendPrecompiledObject(t *testing.T) {
+	type args struct {
+		objectInfo      ObjectInfo
+		sdkToCategories *SdkToCategories
+		pathToObject    string
+		categoryName    string
+	}
+	tests := []struct {
+		name string
+		args args
+		want *SdkToCategories
+	}{
+		{
+			name: "Test append new objects",
+			args: args{
+				objectInfo: ObjectInfo{
+					Name:        "",
+					CloudPath:   "",
+					Description: "",
+					Type:        0,
+					Categories:  []string{"Common"},
+				},
+				sdkToCategories: &SdkToCategories{},
+				pathToObject:    "SDK_JAVA/HelloWorld",
+				categoryName:    "Common",
+			},
+			want: &SdkToCategories{"SDK_JAVA": CategoryToPrecompiledObjects{"Common": PrecompiledObjects{ObjectInfo{
+				Name:        "HelloWorld",
+				CloudPath:   "SDK_JAVA/HelloWorld",
+				Description: "",
+				Type:        0,
+				Categories:  []string{"Common"},
+			}}}},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			appendPrecompiledObject(tt.args.objectInfo, tt.args.sdkToCategories, tt.args.pathToObject, tt.args.categoryName)
+			got := tt.args.sdkToCategories
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("appendPrecompiledObject() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_getFileExtensionBySdk(t *testing.T) {
+	type args struct {
+		precompiledObjectPath string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		wantErr bool
+	}{
+		{
+			// Try to get an extension of a file by the sdk at file path:
+			// SDK_JAVA/HelloWorld -> java
+			name: "Test getFileExtensionBySdk() valid sdk",
+			args:    args{precompiledObjectPath: "SDK_JAVA/HelloWorld"},
+			want:    "java",
+			wantErr: false,
+		},
+		{
+			// Try to get an error if sdk is not a valid one:
+			// INVALID_SDK/HelloWorld -> ""
+			name: "Test getFileExtensionBySdk() invalid sdk",
+			args:    args{precompiledObjectPath: "INVALID_SDK/HelloWorld"},
+			want:    "",
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := getFileExtensionBySdk(tt.args.precompiledObjectPath)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getFileExtensionBySdk() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("getFileExtensionBySdk() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/playground/frontend/lib/api/v1/api.pb.dart b/playground/frontend/lib/api/v1/api.pb.dart
index 9fdcd72..2aef7d9 100644
--- a/playground/frontend/lib/api/v1/api.pb.dart
+++ b/playground/frontend/lib/api/v1/api.pb.dart
@@ -604,15 +604,15 @@ class CancelResponse extends $pb.GeneratedMessage {
   static CancelResponse? _defaultInstance;
 }
 
-class GetListOfExamplesRequest extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetListOfExamplesRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
+class GetPrecompiledObjectsRequest extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetPrecompiledObjectsRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
     ..e<Sdk>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sdk', $pb.PbFieldType.OE, defaultOrMaker: Sdk.SDK_UNSPECIFIED, valueOf: Sdk.valueOf, enumValues: Sdk.values)
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'category')
     ..hasRequiredFields = false
   ;
 
-  GetListOfExamplesRequest._() : super();
-  factory GetListOfExamplesRequest({
+  GetPrecompiledObjectsRequest._() : super();
+  factory GetPrecompiledObjectsRequest({
     Sdk? sdk,
     $core.String? category,
   }) {
@@ -625,26 +625,26 @@ class GetListOfExamplesRequest extends $pb.GeneratedMessage {
     }
     return _result;
   }
-  factory GetListOfExamplesRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory GetListOfExamplesRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory GetPrecompiledObjectsRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetPrecompiledObjectsRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
   'Will be removed in next major version')
-  GetListOfExamplesRequest clone() => GetListOfExamplesRequest()..mergeFromMessage(this);
+  GetPrecompiledObjectsRequest clone() => GetPrecompiledObjectsRequest()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  GetListOfExamplesRequest copyWith(void Function(GetListOfExamplesRequest) updates) => super.copyWith((message) => updates(message as GetListOfExamplesRequest)) as GetListOfExamplesRequest; // ignore: deprecated_member_use
+  GetPrecompiledObjectsRequest copyWith(void Function(GetPrecompiledObjectsRequest) updates) => super.copyWith((message) => updates(message as GetPrecompiledObjectsRequest)) as GetPrecompiledObjectsRequest; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static GetListOfExamplesRequest create() => GetListOfExamplesRequest._();
-  GetListOfExamplesRequest createEmptyInstance() => create();
-  static $pb.PbList<GetListOfExamplesRequest> createRepeated() => $pb.PbList<GetListOfExamplesRequest>();
+  static GetPrecompiledObjectsRequest create() => GetPrecompiledObjectsRequest._();
+  GetPrecompiledObjectsRequest createEmptyInstance() => create();
+  static $pb.PbList<GetPrecompiledObjectsRequest> createRepeated() => $pb.PbList<GetPrecompiledObjectsRequest>();
   @$core.pragma('dart2js:noInline')
-  static GetListOfExamplesRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetListOfExamplesRequest>(create);
-  static GetListOfExamplesRequest? _defaultInstance;
+  static GetPrecompiledObjectsRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetPrecompiledObjectsRequest>(create);
+  static GetPrecompiledObjectsRequest? _defaultInstance;
 
   @$pb.TagNumber(1)
   Sdk get sdk => $_getN(0);
@@ -665,25 +665,25 @@ class GetListOfExamplesRequest extends $pb.GeneratedMessage {
   void clearCategory() => clearField(2);
 }
 
-class Example extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Example', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'exampleUuid')
+class PrecompiledObject extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'PrecompiledObject', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cloudPath')
     ..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'name')
     ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'description')
-    ..e<ExampleType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'type', $pb.PbFieldType.OE, defaultOrMaker: ExampleType.EXAMPLE_TYPE_DEFAULT, valueOf: ExampleType.valueOf, enumValues: ExampleType.values)
+    ..e<PrecompiledObjectType>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'type', $pb.PbFieldType.OE, defaultOrMaker: PrecompiledObjectType.PRECOMPILED_OBJECT_TYPE_UNSPECIFIED, valueOf: PrecompiledObjectType.valueOf, enumValues: PrecompiledObjectType.values)
     ..hasRequiredFields = false
   ;
 
-  Example._() : super();
-  factory Example({
-    $core.String? exampleUuid,
+  PrecompiledObject._() : super();
+  factory PrecompiledObject({
+    $core.String? cloudPath,
     $core.String? name,
     $core.String? description,
-    ExampleType? type,
+    PrecompiledObjectType? type,
   }) {
     final _result = create();
-    if (exampleUuid != null) {
-      _result.exampleUuid = exampleUuid;
+    if (cloudPath != null) {
+      _result.cloudPath = cloudPath;
     }
     if (name != null) {
       _result.name = name;
@@ -696,35 +696,35 @@ class Example extends $pb.GeneratedMessage {
     }
     return _result;
   }
-  factory Example.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory Example.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory PrecompiledObject.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory PrecompiledObject.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
   'Will be removed in next major version')
-  Example clone() => Example()..mergeFromMessage(this);
+  PrecompiledObject clone() => PrecompiledObject()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  Example copyWith(void Function(Example) updates) => super.copyWith((message) => updates(message as Example)) as Example; // ignore: deprecated_member_use
+  PrecompiledObject copyWith(void Function(PrecompiledObject) updates) => super.copyWith((message) => updates(message as PrecompiledObject)) as PrecompiledObject; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static Example create() => Example._();
-  Example createEmptyInstance() => create();
-  static $pb.PbList<Example> createRepeated() => $pb.PbList<Example>();
+  static PrecompiledObject create() => PrecompiledObject._();
+  PrecompiledObject createEmptyInstance() => create();
+  static $pb.PbList<PrecompiledObject> createRepeated() => $pb.PbList<PrecompiledObject>();
   @$core.pragma('dart2js:noInline')
-  static Example getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Example>(create);
-  static Example? _defaultInstance;
+  static PrecompiledObject getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PrecompiledObject>(create);
+  static PrecompiledObject? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get exampleUuid => $_getSZ(0);
+  $core.String get cloudPath => $_getSZ(0);
   @$pb.TagNumber(1)
-  set exampleUuid($core.String v) { $_setString(0, v); }
+  set cloudPath($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasExampleUuid() => $_has(0);
+  $core.bool hasCloudPath() => $_has(0);
   @$pb.TagNumber(1)
-  void clearExampleUuid() => clearField(1);
+  void clearCloudPath() => clearField(1);
 
   @$pb.TagNumber(2)
   $core.String get name => $_getSZ(1);
@@ -745,9 +745,9 @@ class Example extends $pb.GeneratedMessage {
   void clearDescription() => clearField(3);
 
   @$pb.TagNumber(4)
-  ExampleType get type => $_getN(3);
+  PrecompiledObjectType get type => $_getN(3);
   @$pb.TagNumber(4)
-  set type(ExampleType v) { setField(4, v); }
+  set type(PrecompiledObjectType v) { setField(4, v); }
   @$pb.TagNumber(4)
   $core.bool hasType() => $_has(3);
   @$pb.TagNumber(4)
@@ -757,21 +757,21 @@ class Example extends $pb.GeneratedMessage {
 class Categories_Category extends $pb.GeneratedMessage {
   static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Categories.Category', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'categoryName')
-    ..pc<Example>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'examples', $pb.PbFieldType.PM, subBuilder: Example.create)
+    ..pc<PrecompiledObject>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'precompiledObjects', $pb.PbFieldType.PM, subBuilder: PrecompiledObject.create)
     ..hasRequiredFields = false
   ;
 
   Categories_Category._() : super();
   factory Categories_Category({
     $core.String? categoryName,
-    $core.Iterable<Example>? examples,
+    $core.Iterable<PrecompiledObject>? precompiledObjects,
   }) {
     final _result = create();
     if (categoryName != null) {
       _result.categoryName = categoryName;
     }
-    if (examples != null) {
-      _result.examples.addAll(examples);
+    if (precompiledObjects != null) {
+      _result.precompiledObjects.addAll(precompiledObjects);
     }
     return _result;
   }
@@ -806,7 +806,7 @@ class Categories_Category extends $pb.GeneratedMessage {
   void clearCategoryName() => clearField(1);
 
   @$pb.TagNumber(2)
-  $core.List<Example> get examples => $_getList(1);
+  $core.List<PrecompiledObject> get precompiledObjects => $_getList(1);
 }
 
 class Categories extends $pb.GeneratedMessage {
@@ -864,102 +864,102 @@ class Categories extends $pb.GeneratedMessage {
   $core.List<Categories_Category> get categories => $_getList(1);
 }
 
-class GetListOfExamplesResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetListOfExamplesResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
-    ..pc<Categories>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sdkExamples', $pb.PbFieldType.PM, subBuilder: Categories.create)
+class GetPrecompiledObjectsResponse extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetPrecompiledObjectsResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
+    ..pc<Categories>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sdkCategories', $pb.PbFieldType.PM, subBuilder: Categories.create)
     ..hasRequiredFields = false
   ;
 
-  GetListOfExamplesResponse._() : super();
-  factory GetListOfExamplesResponse({
-    $core.Iterable<Categories>? sdkExamples,
+  GetPrecompiledObjectsResponse._() : super();
+  factory GetPrecompiledObjectsResponse({
+    $core.Iterable<Categories>? sdkCategories,
   }) {
     final _result = create();
-    if (sdkExamples != null) {
-      _result.sdkExamples.addAll(sdkExamples);
+    if (sdkCategories != null) {
+      _result.sdkCategories.addAll(sdkCategories);
     }
     return _result;
   }
-  factory GetListOfExamplesResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory GetListOfExamplesResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory GetPrecompiledObjectsResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetPrecompiledObjectsResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
   'Will be removed in next major version')
-  GetListOfExamplesResponse clone() => GetListOfExamplesResponse()..mergeFromMessage(this);
+  GetPrecompiledObjectsResponse clone() => GetPrecompiledObjectsResponse()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  GetListOfExamplesResponse copyWith(void Function(GetListOfExamplesResponse) updates) => super.copyWith((message) => updates(message as GetListOfExamplesResponse)) as GetListOfExamplesResponse; // ignore: deprecated_member_use
+  GetPrecompiledObjectsResponse copyWith(void Function(GetPrecompiledObjectsResponse) updates) => super.copyWith((message) => updates(message as GetPrecompiledObjectsResponse)) as GetPrecompiledObjectsResponse; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static GetListOfExamplesResponse create() => GetListOfExamplesResponse._();
-  GetListOfExamplesResponse createEmptyInstance() => create();
-  static $pb.PbList<GetListOfExamplesResponse> createRepeated() => $pb.PbList<GetListOfExamplesResponse>();
+  static GetPrecompiledObjectsResponse create() => GetPrecompiledObjectsResponse._();
+  GetPrecompiledObjectsResponse createEmptyInstance() => create();
+  static $pb.PbList<GetPrecompiledObjectsResponse> createRepeated() => $pb.PbList<GetPrecompiledObjectsResponse>();
   @$core.pragma('dart2js:noInline')
-  static GetListOfExamplesResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetListOfExamplesResponse>(create);
-  static GetListOfExamplesResponse? _defaultInstance;
+  static GetPrecompiledObjectsResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetPrecompiledObjectsResponse>(create);
+  static GetPrecompiledObjectsResponse? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.List<Categories> get sdkExamples => $_getList(0);
+  $core.List<Categories> get sdkCategories => $_getList(0);
 }
 
-class GetExampleRequest extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetExampleRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
-    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'exampleUuid')
+class GetPrecompiledObjectRequest extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetPrecompiledObjectRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
+    ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'cloudPath')
     ..hasRequiredFields = false
   ;
 
-  GetExampleRequest._() : super();
-  factory GetExampleRequest({
-    $core.String? exampleUuid,
+  GetPrecompiledObjectRequest._() : super();
+  factory GetPrecompiledObjectRequest({
+    $core.String? cloudPath,
   }) {
     final _result = create();
-    if (exampleUuid != null) {
-      _result.exampleUuid = exampleUuid;
+    if (cloudPath != null) {
+      _result.cloudPath = cloudPath;
     }
     return _result;
   }
-  factory GetExampleRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory GetExampleRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory GetPrecompiledObjectRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetPrecompiledObjectRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
   'Will be removed in next major version')
-  GetExampleRequest clone() => GetExampleRequest()..mergeFromMessage(this);
+  GetPrecompiledObjectRequest clone() => GetPrecompiledObjectRequest()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  GetExampleRequest copyWith(void Function(GetExampleRequest) updates) => super.copyWith((message) => updates(message as GetExampleRequest)) as GetExampleRequest; // ignore: deprecated_member_use
+  GetPrecompiledObjectRequest copyWith(void Function(GetPrecompiledObjectRequest) updates) => super.copyWith((message) => updates(message as GetPrecompiledObjectRequest)) as GetPrecompiledObjectRequest; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static GetExampleRequest create() => GetExampleRequest._();
-  GetExampleRequest createEmptyInstance() => create();
-  static $pb.PbList<GetExampleRequest> createRepeated() => $pb.PbList<GetExampleRequest>();
+  static GetPrecompiledObjectRequest create() => GetPrecompiledObjectRequest._();
+  GetPrecompiledObjectRequest createEmptyInstance() => create();
+  static $pb.PbList<GetPrecompiledObjectRequest> createRepeated() => $pb.PbList<GetPrecompiledObjectRequest>();
   @$core.pragma('dart2js:noInline')
-  static GetExampleRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetExampleRequest>(create);
-  static GetExampleRequest? _defaultInstance;
+  static GetPrecompiledObjectRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetPrecompiledObjectRequest>(create);
+  static GetPrecompiledObjectRequest? _defaultInstance;
 
   @$pb.TagNumber(1)
-  $core.String get exampleUuid => $_getSZ(0);
+  $core.String get cloudPath => $_getSZ(0);
   @$pb.TagNumber(1)
-  set exampleUuid($core.String v) { $_setString(0, v); }
+  set cloudPath($core.String v) { $_setString(0, v); }
   @$pb.TagNumber(1)
-  $core.bool hasExampleUuid() => $_has(0);
+  $core.bool hasCloudPath() => $_has(0);
   @$pb.TagNumber(1)
-  void clearExampleUuid() => clearField(1);
+  void clearCloudPath() => clearField(1);
 }
 
-class GetExampleResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetExampleResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
+class GetPrecompiledObjectCodeResponse extends $pb.GeneratedMessage {
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetPrecompiledObjectCodeResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'api.v1'), createEmptyInstance: create)
     ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'code')
     ..hasRequiredFields = false
   ;
 
-  GetExampleResponse._() : super();
-  factory GetExampleResponse({
+  GetPrecompiledObjectCodeResponse._() : super();
+  factory GetPrecompiledObjectCodeResponse({
     $core.String? code,
   }) {
     final _result = create();
@@ -968,26 +968,26 @@ class GetExampleResponse extends $pb.GeneratedMessage {
     }
     return _result;
   }
-  factory GetExampleResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
-  factory GetExampleResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
+  factory GetPrecompiledObjectCodeResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
+  factory GetPrecompiledObjectCodeResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
   'Will be removed in next major version')
-  GetExampleResponse clone() => GetExampleResponse()..mergeFromMessage(this);
+  GetPrecompiledObjectCodeResponse clone() => GetPrecompiledObjectCodeResponse()..mergeFromMessage(this);
   @$core.Deprecated(
   'Using this can add significant overhead to your binary. '
   'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
   'Will be removed in next major version')
-  GetExampleResponse copyWith(void Function(GetExampleResponse) updates) => super.copyWith((message) => updates(message as GetExampleResponse)) as GetExampleResponse; // ignore: deprecated_member_use
+  GetPrecompiledObjectCodeResponse copyWith(void Function(GetPrecompiledObjectCodeResponse) updates) => super.copyWith((message) => updates(message as GetPrecompiledObjectCodeResponse)) as GetPrecompiledObjectCodeResponse; // ignore: deprecated_member_use
   $pb.BuilderInfo get info_ => _i;
   @$core.pragma('dart2js:noInline')
-  static GetExampleResponse create() => GetExampleResponse._();
-  GetExampleResponse createEmptyInstance() => create();
-  static $pb.PbList<GetExampleResponse> createRepeated() => $pb.PbList<GetExampleResponse>();
+  static GetPrecompiledObjectCodeResponse create() => GetPrecompiledObjectCodeResponse._();
+  GetPrecompiledObjectCodeResponse createEmptyInstance() => create();
+  static $pb.PbList<GetPrecompiledObjectCodeResponse> createRepeated() => $pb.PbList<GetPrecompiledObjectCodeResponse>();
   @$core.pragma('dart2js:noInline')
-  static GetExampleResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetExampleResponse>(create);
-  static GetExampleResponse? _defaultInstance;
+  static GetPrecompiledObjectCodeResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetPrecompiledObjectCodeResponse>(create);
+  static GetPrecompiledObjectCodeResponse? _defaultInstance;
 
   @$pb.TagNumber(1)
   $core.String get code => $_getSZ(0);
diff --git a/playground/frontend/lib/api/v1/api.pbenum.dart b/playground/frontend/lib/api/v1/api.pbenum.dart
index b22fb5d..83a7729 100644
--- a/playground/frontend/lib/api/v1/api.pbenum.dart
+++ b/playground/frontend/lib/api/v1/api.pbenum.dart
@@ -84,20 +84,22 @@ class Status extends $pb.ProtobufEnum {
   const Status._($core.int v, $core.String n) : super(v, n);
 }
 
-class ExampleType extends $pb.ProtobufEnum {
-  static const ExampleType EXAMPLE_TYPE_DEFAULT = ExampleType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EXAMPLE_TYPE_DEFAULT');
-  static const ExampleType EXAMPLE_TYPE_KATA = ExampleType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EXAMPLE_TYPE_KATA');
-  static const ExampleType EXAMPLE_TYPE_UNIT_TEST = ExampleType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EXAMPLE_TYPE_UNIT_TEST');
+class PrecompiledObjectType extends $pb.ProtobufEnum {
+  static const PrecompiledObjectType PRECOMPILED_OBJECT_TYPE_UNSPECIFIED = PrecompiledObjectType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PRECOMPILED_OBJECT_TYPE_UNSPECIFIED');
+  static const PrecompiledObjectType PRECOMPILED_OBJECT_TYPE_EXAMPLE = PrecompiledObjectType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PRECOMPILED_OBJECT_TYPE_EXAMPLE');
+  static const PrecompiledObjectType PRECOMPILED_OBJECT_TYPE_KATA = PrecompiledObjectType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PRECOMPILED_OBJECT_TYPE_KATA');
+  static const PrecompiledObjectType PRECOMPILED_OBJECT_TYPE_UNIT_TEST = PrecompiledObjectType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PRECOMPILED_OBJECT_TYPE_UNIT_TEST');
 
-  static const $core.List<ExampleType> values = <ExampleType> [
-    EXAMPLE_TYPE_DEFAULT,
-    EXAMPLE_TYPE_KATA,
-    EXAMPLE_TYPE_UNIT_TEST,
+  static const $core.List<PrecompiledObjectType> values = <PrecompiledObjectType> [
+    PRECOMPILED_OBJECT_TYPE_UNSPECIFIED,
+    PRECOMPILED_OBJECT_TYPE_EXAMPLE,
+    PRECOMPILED_OBJECT_TYPE_KATA,
+    PRECOMPILED_OBJECT_TYPE_UNIT_TEST,
   ];
 
-  static final $core.Map<$core.int, ExampleType> _byValue = $pb.ProtobufEnum.initByValue(values);
-  static ExampleType? valueOf($core.int value) => _byValue[value];
+  static final $core.Map<$core.int, PrecompiledObjectType> _byValue = $pb.ProtobufEnum.initByValue(values);
+  static PrecompiledObjectType? valueOf($core.int value) => _byValue[value];
 
-  const ExampleType._($core.int v, $core.String n) : super(v, n);
+  const PrecompiledObjectType._($core.int v, $core.String n) : super(v, n);
 }
 
diff --git a/playground/frontend/lib/api/v1/api.pbgrpc.dart b/playground/frontend/lib/api/v1/api.pbgrpc.dart
index bc7b50b..4f568c1 100644
--- a/playground/frontend/lib/api/v1/api.pbgrpc.dart
+++ b/playground/frontend/lib/api/v1/api.pbgrpc.dart
@@ -67,24 +67,24 @@ class PlaygroundServiceClient extends $grpc.Client {
           '/api.v1.PlaygroundService/Cancel',
           ($0.CancelRequest value) => value.writeToBuffer(),
           ($core.List<$core.int> value) => $0.CancelResponse.fromBuffer(value));
-  static final _$getListOfExamples = $grpc.ClientMethod<
-          $0.GetListOfExamplesRequest, $0.GetListOfExamplesResponse>(
-      '/api.v1.PlaygroundService/GetListOfExamples',
-      ($0.GetListOfExamplesRequest value) => value.writeToBuffer(),
+  static final _$getPrecompiledObjects = $grpc.ClientMethod<
+          $0.GetPrecompiledObjectsRequest, $0.GetPrecompiledObjectsResponse>(
+      '/api.v1.PlaygroundService/GetPrecompiledObjects',
+      ($0.GetPrecompiledObjectsRequest value) => value.writeToBuffer(),
       ($core.List<$core.int> value) =>
-          $0.GetListOfExamplesResponse.fromBuffer(value));
-  static final _$getExample =
-      $grpc.ClientMethod<$0.GetExampleRequest, $0.GetExampleResponse>(
-          '/api.v1.PlaygroundService/GetExample',
-          ($0.GetExampleRequest value) => value.writeToBuffer(),
-          ($core.List<$core.int> value) =>
-              $0.GetExampleResponse.fromBuffer(value));
-  static final _$getExampleOutput =
-      $grpc.ClientMethod<$0.GetExampleRequest, $0.GetRunOutputResponse>(
-          '/api.v1.PlaygroundService/GetExampleOutput',
-          ($0.GetExampleRequest value) => value.writeToBuffer(),
-          ($core.List<$core.int> value) =>
-              $0.GetRunOutputResponse.fromBuffer(value));
+          $0.GetPrecompiledObjectsResponse.fromBuffer(value));
+  static final _$getPrecompiledObjectCode = $grpc.ClientMethod<
+          $0.GetPrecompiledObjectRequest, $0.GetPrecompiledObjectCodeResponse>(
+      '/api.v1.PlaygroundService/GetPrecompiledObjectCode',
+      ($0.GetPrecompiledObjectRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) =>
+          $0.GetPrecompiledObjectCodeResponse.fromBuffer(value));
+  static final _$getPrecompiledObjectOutput = $grpc.ClientMethod<
+          $0.GetPrecompiledObjectRequest, $0.GetRunOutputResponse>(
+      '/api.v1.PlaygroundService/GetPrecompiledObjectOutput',
+      ($0.GetPrecompiledObjectRequest value) => value.writeToBuffer(),
+      ($core.List<$core.int> value) =>
+          $0.GetRunOutputResponse.fromBuffer(value));
 
   PlaygroundServiceClient($grpc.ClientChannel channel,
       {$grpc.CallOptions? options,
@@ -125,22 +125,24 @@ class PlaygroundServiceClient extends $grpc.Client {
     return $createUnaryCall(_$cancel, request, options: options);
   }
 
-  $grpc.ResponseFuture<$0.GetListOfExamplesResponse> getListOfExamples(
-      $0.GetListOfExamplesRequest request,
+  $grpc.ResponseFuture<$0.GetPrecompiledObjectsResponse> getPrecompiledObjects(
+      $0.GetPrecompiledObjectsRequest request,
       {$grpc.CallOptions? options}) {
-    return $createUnaryCall(_$getListOfExamples, request, options: options);
+    return $createUnaryCall(_$getPrecompiledObjects, request, options: options);
   }
 
-  $grpc.ResponseFuture<$0.GetExampleResponse> getExample(
-      $0.GetExampleRequest request,
-      {$grpc.CallOptions? options}) {
-    return $createUnaryCall(_$getExample, request, options: options);
+  $grpc.ResponseFuture<$0.GetPrecompiledObjectCodeResponse>
+      getPrecompiledObjectCode($0.GetPrecompiledObjectRequest request,
+          {$grpc.CallOptions? options}) {
+    return $createUnaryCall(_$getPrecompiledObjectCode, request,
+        options: options);
   }
 
-  $grpc.ResponseFuture<$0.GetRunOutputResponse> getExampleOutput(
-      $0.GetExampleRequest request,
+  $grpc.ResponseFuture<$0.GetRunOutputResponse> getPrecompiledObjectOutput(
+      $0.GetPrecompiledObjectRequest request,
       {$grpc.CallOptions? options}) {
-    return $createUnaryCall(_$getExampleOutput, request, options: options);
+    return $createUnaryCall(_$getPrecompiledObjectOutput, request,
+        options: options);
   }
 }
 
@@ -198,31 +200,33 @@ abstract class PlaygroundServiceBase extends $grpc.Service {
         false,
         ($core.List<$core.int> value) => $0.CancelRequest.fromBuffer(value),
         ($0.CancelResponse value) => value.writeToBuffer()));
-    $addMethod($grpc.ServiceMethod<$0.GetListOfExamplesRequest,
-            $0.GetListOfExamplesResponse>(
-        'GetListOfExamples',
-        getListOfExamples_Pre,
+    $addMethod($grpc.ServiceMethod<$0.GetPrecompiledObjectsRequest,
+            $0.GetPrecompiledObjectsResponse>(
+        'GetPrecompiledObjects',
+        getPrecompiledObjects_Pre,
         false,
         false,
         ($core.List<$core.int> value) =>
-            $0.GetListOfExamplesRequest.fromBuffer(value),
-        ($0.GetListOfExamplesResponse value) => value.writeToBuffer()));
-    $addMethod($grpc.ServiceMethod<$0.GetExampleRequest, $0.GetExampleResponse>(
-        'GetExample',
-        getExample_Pre,
+            $0.GetPrecompiledObjectsRequest.fromBuffer(value),
+        ($0.GetPrecompiledObjectsResponse value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.GetPrecompiledObjectRequest,
+            $0.GetPrecompiledObjectCodeResponse>(
+        'GetPrecompiledObjectCode',
+        getPrecompiledObjectCode_Pre,
         false,
         false,
-        ($core.List<$core.int> value) => $0.GetExampleRequest.fromBuffer(value),
-        ($0.GetExampleResponse value) => value.writeToBuffer()));
-    $addMethod(
-        $grpc.ServiceMethod<$0.GetExampleRequest, $0.GetRunOutputResponse>(
-            'GetExampleOutput',
-            getExampleOutput_Pre,
-            false,
-            false,
-            ($core.List<$core.int> value) =>
-                $0.GetExampleRequest.fromBuffer(value),
-            ($0.GetRunOutputResponse value) => value.writeToBuffer()));
+        ($core.List<$core.int> value) =>
+            $0.GetPrecompiledObjectRequest.fromBuffer(value),
+        ($0.GetPrecompiledObjectCodeResponse value) => value.writeToBuffer()));
+    $addMethod($grpc.ServiceMethod<$0.GetPrecompiledObjectRequest,
+            $0.GetRunOutputResponse>(
+        'GetPrecompiledObjectOutput',
+        getPrecompiledObjectOutput_Pre,
+        false,
+        false,
+        ($core.List<$core.int> value) =>
+            $0.GetPrecompiledObjectRequest.fromBuffer(value),
+        ($0.GetRunOutputResponse value) => value.writeToBuffer()));
   }
 
   $async.Future<$0.RunCodeResponse> runCode_Pre(
@@ -257,21 +261,22 @@ abstract class PlaygroundServiceBase extends $grpc.Service {
     return cancel(call, await request);
   }
 
-  $async.Future<$0.GetListOfExamplesResponse> getListOfExamples_Pre(
+  $async.Future<$0.GetPrecompiledObjectsResponse> getPrecompiledObjects_Pre(
       $grpc.ServiceCall call,
-      $async.Future<$0.GetListOfExamplesRequest> request) async {
-    return getListOfExamples(call, await request);
+      $async.Future<$0.GetPrecompiledObjectsRequest> request) async {
+    return getPrecompiledObjects(call, await request);
   }
 
-  $async.Future<$0.GetExampleResponse> getExample_Pre($grpc.ServiceCall call,
-      $async.Future<$0.GetExampleRequest> request) async {
-    return getExample(call, await request);
+  $async.Future<$0.GetPrecompiledObjectCodeResponse>
+      getPrecompiledObjectCode_Pre($grpc.ServiceCall call,
+          $async.Future<$0.GetPrecompiledObjectRequest> request) async {
+    return getPrecompiledObjectCode(call, await request);
   }
 
-  $async.Future<$0.GetRunOutputResponse> getExampleOutput_Pre(
+  $async.Future<$0.GetRunOutputResponse> getPrecompiledObjectOutput_Pre(
       $grpc.ServiceCall call,
-      $async.Future<$0.GetExampleRequest> request) async {
-    return getExampleOutput(call, await request);
+      $async.Future<$0.GetPrecompiledObjectRequest> request) async {
+    return getPrecompiledObjectOutput(call, await request);
   }
 
   $async.Future<$0.RunCodeResponse> runCode(
@@ -286,10 +291,10 @@ abstract class PlaygroundServiceBase extends $grpc.Service {
       $grpc.ServiceCall call, $0.GetCompileOutputRequest request);
   $async.Future<$0.CancelResponse> cancel(
       $grpc.ServiceCall call, $0.CancelRequest request);
-  $async.Future<$0.GetListOfExamplesResponse> getListOfExamples(
-      $grpc.ServiceCall call, $0.GetListOfExamplesRequest request);
-  $async.Future<$0.GetExampleResponse> getExample(
-      $grpc.ServiceCall call, $0.GetExampleRequest request);
-  $async.Future<$0.GetRunOutputResponse> getExampleOutput(
-      $grpc.ServiceCall call, $0.GetExampleRequest request);
+  $async.Future<$0.GetPrecompiledObjectsResponse> getPrecompiledObjects(
+      $grpc.ServiceCall call, $0.GetPrecompiledObjectsRequest request);
+  $async.Future<$0.GetPrecompiledObjectCodeResponse> getPrecompiledObjectCode(
+      $grpc.ServiceCall call, $0.GetPrecompiledObjectRequest request);
+  $async.Future<$0.GetRunOutputResponse> getPrecompiledObjectOutput(
+      $grpc.ServiceCall call, $0.GetPrecompiledObjectRequest request);
 }
diff --git a/playground/frontend/lib/api/v1/api.pbjson.dart b/playground/frontend/lib/api/v1/api.pbjson.dart
index 3c90693..0e0209c 100644
--- a/playground/frontend/lib/api/v1/api.pbjson.dart
+++ b/playground/frontend/lib/api/v1/api.pbjson.dart
@@ -61,18 +61,19 @@ const Status$json = const {
 
 /// Descriptor for `Status`. Decode as a `google.protobuf.EnumDescriptorProto`.
 final $typed_data.Uint8List statusDescriptor = $convert.base64Decode('CgZTdGF0dXMSFgoSU1RBVFVTX1VOU1BFQ0lGSUVEEAASFQoRU1RBVFVTX1ZBTElEQVRJTkcQARIbChdTVEFUVVNfVkFMSURBVElPTl9FUlJPUhACEhQKEFNUQVRVU19QUkVQQVJJTkcQAxIcChhTVEFUVVNfUFJFUEFSQVRJT05fRVJST1IQBBIUChBTVEFUVVNfQ09NUElMSU5HEAUSGAoUU1RBVFVTX0NPTVBJTEVfRVJST1IQBhIUChBTVEFUVVNfRVhFQ1VUSU5HEAcSEwoPU1RBVFVTX0ZJTklTSEVEEAgSFAoQU1RBVFVTX1JVTl9FUlJPUhAJEhAKDFNUQVRVU19FUlJPUhAKEhYKElNUQVRVU19SVU5fVElNRU9VVBALEhMKD1NUQVRVU19DQU5DRUxFRBAM');
-@$core.Deprecated('Use exampleTypeDescriptor instead')
-const ExampleType$json = const {
-  '1': 'ExampleType',
+@$core.Deprecated('Use precompiledObjectTypeDescriptor instead')
+const PrecompiledObjectType$json = const {
+  '1': 'PrecompiledObjectType',
   '2': const [
-    const {'1': 'EXAMPLE_TYPE_DEFAULT', '2': 0},
-    const {'1': 'EXAMPLE_TYPE_KATA', '2': 1},
-    const {'1': 'EXAMPLE_TYPE_UNIT_TEST', '2': 2},
+    const {'1': 'PRECOMPILED_OBJECT_TYPE_UNSPECIFIED', '2': 0},
+    const {'1': 'PRECOMPILED_OBJECT_TYPE_EXAMPLE', '2': 1},
+    const {'1': 'PRECOMPILED_OBJECT_TYPE_KATA', '2': 2},
+    const {'1': 'PRECOMPILED_OBJECT_TYPE_UNIT_TEST', '2': 3},
   ],
 };
 
-/// Descriptor for `ExampleType`. Decode as a `google.protobuf.EnumDescriptorProto`.
-final $typed_data.Uint8List exampleTypeDescriptor = $convert.base64Decode('CgtFeGFtcGxlVHlwZRIYChRFWEFNUExFX1RZUEVfREVGQVVMVBAAEhUKEUVYQU1QTEVfVFlQRV9LQVRBEAESGgoWRVhBTVBMRV9UWVBFX1VOSVRfVEVTVBAC');
+/// Descriptor for `PrecompiledObjectType`. Decode as a `google.protobuf.EnumDescriptorProto`.
+final $typed_data.Uint8List precompiledObjectTypeDescriptor = $convert.base64Decode('ChVQcmVjb21waWxlZE9iamVjdFR5cGUSJwojUFJFQ09NUElMRURfT0JKRUNUX1RZUEVfVU5TUEVDSUZJRUQQABIjCh9QUkVDT01QSUxFRF9PQkpFQ1RfVFlQRV9FWEFNUExFEAESIAocUFJFQ09NUElMRURfT0JKRUNUX1RZUEVfS0FUQRACEiUKIVBSRUNPTVBJTEVEX09CSkVDVF9UWVBFX1VOSVRfVEVTVBAD');
 @$core.Deprecated('Use runCodeRequestDescriptor instead')
 const RunCodeRequest$json = const {
   '1': 'RunCodeRequest',
@@ -192,30 +193,30 @@ const CancelResponse$json = const {
 
 /// Descriptor for `CancelResponse`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List cancelResponseDescriptor = $convert.base64Decode('Cg5DYW5jZWxSZXNwb25zZQ==');
-@$core.Deprecated('Use getListOfExamplesRequestDescriptor instead')
-const GetListOfExamplesRequest$json = const {
-  '1': 'GetListOfExamplesRequest',
+@$core.Deprecated('Use getPrecompiledObjectsRequestDescriptor instead')
+const GetPrecompiledObjectsRequest$json = const {
+  '1': 'GetPrecompiledObjectsRequest',
   '2': const [
     const {'1': 'sdk', '3': 1, '4': 1, '5': 14, '6': '.api.v1.Sdk', '10': 'sdk'},
     const {'1': 'category', '3': 2, '4': 1, '5': 9, '10': 'category'},
   ],
 };
 
-/// Descriptor for `GetListOfExamplesRequest`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List getListOfExamplesRequestDescriptor = $convert.base64Decode('ChhHZXRMaXN0T2ZFeGFtcGxlc1JlcXVlc3QSHQoDc2RrGAEgASgOMgsuYXBpLnYxLlNka1IDc2RrEhoKCGNhdGVnb3J5GAIgASgJUghjYXRlZ29yeQ==');
-@$core.Deprecated('Use exampleDescriptor instead')
-const Example$json = const {
-  '1': 'Example',
+/// Descriptor for `GetPrecompiledObjectsRequest`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getPrecompiledObjectsRequestDescriptor = $convert.base64Decode('ChxHZXRQcmVjb21waWxlZE9iamVjdHNSZXF1ZXN0Eh0KA3NkaxgBIAEoDjILLmFwaS52MS5TZGtSA3NkaxIaCghjYXRlZ29yeRgCIAEoCVIIY2F0ZWdvcnk=');
+@$core.Deprecated('Use precompiledObjectDescriptor instead')
+const PrecompiledObject$json = const {
+  '1': 'PrecompiledObject',
   '2': const [
-    const {'1': 'example_uuid', '3': 1, '4': 1, '5': 9, '10': 'exampleUuid'},
+    const {'1': 'cloud_path', '3': 1, '4': 1, '5': 9, '10': 'cloudPath'},
     const {'1': 'name', '3': 2, '4': 1, '5': 9, '10': 'name'},
     const {'1': 'description', '3': 3, '4': 1, '5': 9, '10': 'description'},
-    const {'1': 'type', '3': 4, '4': 1, '5': 14, '6': '.api.v1.ExampleType', '10': 'type'},
+    const {'1': 'type', '3': 4, '4': 1, '5': 14, '6': '.api.v1.PrecompiledObjectType', '10': 'type'},
   ],
 };
 
-/// Descriptor for `Example`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List exampleDescriptor = $convert.base64Decode('CgdFeGFtcGxlEiEKDGV4YW1wbGVfdXVpZBgBIAEoCVILZXhhbXBsZVV1aWQSEgoEbmFtZRgCIAEoCVIEbmFtZRIgCgtkZXNjcmlwdGlvbhgDIAEoCVILZGVzY3JpcHRpb24SJwoEdHlwZRgEIAEoDjITLmFwaS52MS5FeGFtcGxlVHlwZVIEdHlwZQ==');
+/// Descriptor for `PrecompiledObject`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List precompiledObjectDescriptor = $convert.base64Decode('ChFQcmVjb21waWxlZE9iamVjdBIdCgpjbG91ZF9wYXRoGAEgASgJUgljbG91ZFBhdGgSEgoEbmFtZRgCIAEoCVIEbmFtZRIgCgtkZXNjcmlwdGlvbhgDIAEoCVILZGVzY3JpcHRpb24SMQoEdHlwZRgEIAEoDjIdLmFwaS52MS5QcmVjb21waWxlZE9iamVjdFR5cGVSBHR5cGU=');
 @$core.Deprecated('Use categoriesDescriptor instead')
 const Categories$json = const {
   '1': 'Categories',
@@ -231,39 +232,39 @@ const Categories_Category$json = const {
   '1': 'Category',
   '2': const [
     const {'1': 'category_name', '3': 1, '4': 1, '5': 9, '10': 'categoryName'},
-    const {'1': 'examples', '3': 2, '4': 3, '5': 11, '6': '.api.v1.Example', '10': 'examples'},
+    const {'1': 'precompiled_objects', '3': 2, '4': 3, '5': 11, '6': '.api.v1.PrecompiledObject', '10': 'precompiledObjects'},
   ],
 };
 
 /// Descriptor for `Categories`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List categoriesDescriptor = $convert.base64Decode('CgpDYXRlZ29yaWVzEh0KA3NkaxgBIAEoDjILLmFwaS52MS5TZGtSA3NkaxI7CgpjYXRlZ29yaWVzGAIgAygLMhsuYXBpLnYxLkNhdGVnb3JpZXMuQ2F0ZWdvcnlSCmNhdGVnb3JpZXMaXAoIQ2F0ZWdvcnkSIwoNY2F0ZWdvcnlfbmFtZRgBIAEoCVIMY2F0ZWdvcnlOYW1lEisKCGV4YW1wbGVzGAIgAygLMg8uYXBpLnYxLkV4YW1wbGVSCGV4YW1wbGVz');
-@$core.Deprecated('Use getListOfExamplesResponseDescriptor instead')
-const GetListOfExamplesResponse$json = const {
-  '1': 'GetListOfExamplesResponse',
+final $typed_data.Uint8List categoriesDescriptor = $convert.base64Decode('CgpDYXRlZ29yaWVzEh0KA3NkaxgBIAEoDjILLmFwaS52MS5TZGtSA3NkaxI7CgpjYXRlZ29yaWVzGAIgAygLMhsuYXBpLnYxLkNhdGVnb3JpZXMuQ2F0ZWdvcnlSCmNhdGVnb3JpZXMaewoIQ2F0ZWdvcnkSIwoNY2F0ZWdvcnlfbmFtZRgBIAEoCVIMY2F0ZWdvcnlOYW1lEkoKE3ByZWNvbXBpbGVkX29iamVjdHMYAiADKAsyGS5hcGkudjEuUHJlY29tcGlsZWRPYmplY3RSEnByZWNvbXBpbGVkT2JqZWN0cw==');
+@$core.Deprecated('Use getPrecompiledObjectsResponseDescriptor instead')
+const GetPrecompiledObjectsResponse$json = const {
+  '1': 'GetPrecompiledObjectsResponse',
   '2': const [
-    const {'1': 'sdk_examples', '3': 1, '4': 3, '5': 11, '6': '.api.v1.Categories', '10': 'sdkExamples'},
+    const {'1': 'sdk_categories', '3': 1, '4': 3, '5': 11, '6': '.api.v1.Categories', '10': 'sdkCategories'},
   ],
 };
 
-/// Descriptor for `GetListOfExamplesResponse`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List getListOfExamplesResponseDescriptor = $convert.base64Decode('ChlHZXRMaXN0T2ZFeGFtcGxlc1Jlc3BvbnNlEjUKDHNka19leGFtcGxlcxgBIAMoCzISLmFwaS52MS5DYXRlZ29yaWVzUgtzZGtFeGFtcGxlcw==');
-@$core.Deprecated('Use getExampleRequestDescriptor instead')
-const GetExampleRequest$json = const {
-  '1': 'GetExampleRequest',
+/// Descriptor for `GetPrecompiledObjectsResponse`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getPrecompiledObjectsResponseDescriptor = $convert.base64Decode('Ch1HZXRQcmVjb21waWxlZE9iamVjdHNSZXNwb25zZRI5Cg5zZGtfY2F0ZWdvcmllcxgBIAMoCzISLmFwaS52MS5DYXRlZ29yaWVzUg1zZGtDYXRlZ29yaWVz');
+@$core.Deprecated('Use getPrecompiledObjectRequestDescriptor instead')
+const GetPrecompiledObjectRequest$json = const {
+  '1': 'GetPrecompiledObjectRequest',
   '2': const [
-    const {'1': 'example_uuid', '3': 1, '4': 1, '5': 9, '10': 'exampleUuid'},
+    const {'1': 'cloud_path', '3': 1, '4': 1, '5': 9, '10': 'cloudPath'},
   ],
 };
 
-/// Descriptor for `GetExampleRequest`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List getExampleRequestDescriptor = $convert.base64Decode('ChFHZXRFeGFtcGxlUmVxdWVzdBIhCgxleGFtcGxlX3V1aWQYASABKAlSC2V4YW1wbGVVdWlk');
-@$core.Deprecated('Use getExampleResponseDescriptor instead')
-const GetExampleResponse$json = const {
-  '1': 'GetExampleResponse',
+/// Descriptor for `GetPrecompiledObjectRequest`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getPrecompiledObjectRequestDescriptor = $convert.base64Decode('ChtHZXRQcmVjb21waWxlZE9iamVjdFJlcXVlc3QSHQoKY2xvdWRfcGF0aBgBIAEoCVIJY2xvdWRQYXRo');
+@$core.Deprecated('Use getPrecompiledObjectCodeResponseDescriptor instead')
+const GetPrecompiledObjectCodeResponse$json = const {
+  '1': 'GetPrecompiledObjectCodeResponse',
   '2': const [
     const {'1': 'code', '3': 1, '4': 1, '5': 9, '10': 'code'},
   ],
 };
 
-/// Descriptor for `GetExampleResponse`. Decode as a `google.protobuf.DescriptorProto`.
-final $typed_data.Uint8List getExampleResponseDescriptor = $convert.base64Decode('ChJHZXRFeGFtcGxlUmVzcG9uc2USEgoEY29kZRgBIAEoCVIEY29kZQ==');
+/// Descriptor for `GetPrecompiledObjectCodeResponse`. Decode as a `google.protobuf.DescriptorProto`.
+final $typed_data.Uint8List getPrecompiledObjectCodeResponseDescriptor = $convert.base64Decode('CiBHZXRQcmVjb21waWxlZE9iamVjdENvZGVSZXNwb25zZRISCgRjb2RlGAEgASgJUgRjb2Rl');