@@ -446,7 +446,7 @@ C# Code
```csharp
using KclLib.API;
-var args = new RenameCode_Args
+var args = new RenameCodeArgs
{
PackageRoot = "/mock/path",
SymbolPath = "a",
@@ -472,7 +472,7 @@ C# Code
using KclLib.API;
var pkg = Path.Combine(parentDirectory, "test_data", "testing");
-var args = new Test_Args();
+var args = new TestArgs();
args.PkgList.Add(pkg + "/...");
var result = new API().Test(args);
```
@@ -504,7 +504,7 @@ using KclLib.API;
var workDir = ".";
var settingsFile = "kcl.yaml";
-var args = new LoadSettingsFiles_Args
+var args = new LoadSettingsFilesArgs
{
WorkDir = workDir,
};
@@ -541,7 +541,7 @@ C# Code
using KclLib.API;
var manifestPath = "module";
-var args = new UpdateDependencies_Args { ManifestPath = manifestPath };
+var args = new UpdateDependenciesArgs { ManifestPath = manifestPath };
var result = new API().UpdateDependencies(args);
```
@@ -584,9 +584,9 @@ API api = new API();
var manifestPath = "module";
var testFile = Path.Combine(manifestPath, "main.k");
-var updateArgs = new UpdateDependencies_Args { ManifestPath = manifestPath };
+var updateArgs = new UpdateDependenciesArgs { ManifestPath = manifestPath };
var depResult = new API().UpdateDependencies(updateArgs);
-var execArgs = new ExecProgram_Args();
+var execArgs = new ExecProgramArgs();
execArgs.KFilenameList.Add(testFile);
execArgs.ExternalPkgs.AddRange(depResult.ExternalPkgs);
var execResult = new API().ExecProgram(execArgs);
@@ -607,7 +607,7 @@ C# Code
```csharp
using KclLib.API;
-var result = new API().GetVersion(new GetVersion_Args());
+var result = new API().GetVersion(new GetVersionArgs());
```
diff --git a/docs/reference/xlang-api/go-api.md b/docs/reference/xlang-api/go-api.md
index 739bb18c2..3c255e38e 100644
--- a/docs/reference/xlang-api/go-api.md
+++ b/docs/reference/xlang-api/go-api.md
@@ -7,7 +7,7 @@ sidebar_position: 3
```go
-import kcl "kcl-lang.io/kcl-go"
+import "kcl-lang.io/kcl-go"
```
```
@@ -90,82 +90,16 @@ x1 = Person {
-## Index
-
-- [Go API](#go-api)
- - [Index](#index)
- - [Constants](#constants)
- - [func FormatCode](#func-formatcode)
- - [func FormatPath](#func-formatpath)
- - [func GetSchemaTypeMapping](#func-getschematypemapping)
- - [func InitKclvmPath](#func-initkclvmpath)
- - [func InitKclvmRuntime](#func-initkclvmruntime)
- - [func LintPath](#func-lintpath)
- - [func ListDepFiles](#func-listdepfiles)
- - [func ListDownStreamFiles](#func-listdownstreamfiles)
- - [func ListUpStreamFiles](#func-listupstreamfiles)
- - [func OverrideFile](#func-overridefile)
- - [func Validate](#func-validate)
- - [func ValidateCode](#func-validatecode)
- - [type KCLResult](#type-kclresult)
- - [type KCLResultList](#type-kclresultlist)
- - [func MustRun](#func-mustrun)
- - [func Run](#func-run)
- - [func RunFiles](#func-runfiles)
- - [type KclType](#type-kcltype)
- - [func GetSchemaType](#func-getschematype)
- - [type ListDepFilesOption](#type-listdepfilesoption)
- - [type ListDepsOptions](#type-listdepsoptions)
- - [type ListOptionsArgs](#type-listoptionsargs)
- - [type ListOptionsResult](#type-listoptionsresult)
- - [func ListOptions](#func-listoptions)
- - [type ListVariablesArgs](#type-listvariablesargs)
- - [type ListVariablesResult](#type-listvariablesresult)
- - [func ListVariables](#func-listvariables)
- - [type LoadPackageArgs](#type-loadpackageargs)
- - [type LoadPackageResult](#type-loadpackageresult)
- - [func LoadPackage](#func-loadpackage)
- - [type Option](#type-option)
- - [func NewOption](#func-newoption)
- - [func WithCode](#func-withcode)
- - [func WithDisableNone](#func-withdisablenone)
- - [func WithExternalPkgAndPath](#func-withexternalpkgandpath)
- - [func WithExternalPkgs](#func-withexternalpkgs)
- - [func WithFullTypePath](#func-withfulltypepath)
- - [func WithIncludeSchemaTypePath](#func-withincludeschematypepath)
- - [func WithKFilenames](#func-withkfilenames)
- - [func WithLogger](#func-withlogger)
- - [func WithOptions](#func-withoptions)
- - [func WithOverrides](#func-withoverrides)
- - [func WithPrintOverridesAST](#func-withprintoverridesast)
- - [func WithSelectors](#func-withselectors)
- - [func WithSettings](#func-withsettings)
- - [func WithShowHidden](#func-withshowhidden)
- - [func WithSortKeys](#func-withsortkeys)
- - [func WithWorkDir](#func-withworkdir)
- - [type ParseProgramArgs](#type-parseprogramargs)
- - [type ParseProgramResult](#type-parseprogramresult)
- - [func ParseProgram](#func-parseprogram)
- - [type TestCaseInfo](#type-testcaseinfo)
- - [type TestOptions](#type-testoptions)
- - [type TestResult](#type-testresult)
- - [func Test](#func-test)
- - [type UpdateDependenciesArgs](#type-updatedependenciesargs)
- - [type UpdateDependenciesResult](#type-updatedependenciesresult)
- - [func UpdateDependencies](#func-updatedependencies)
- - [type ValidateOptions](#type-validateoptions)
- - [type VersionResult](#type-versionresult)
- - [func GetVersion](#func-getversion)
## Constants
-KclvmAbiVersion is the current kclvm ABI version.
+KclAbiVersion is the current kcl ABI version.
```go
-const KclvmAbiVersion = scripts.KclvmAbiVersion
+const KclAbiVersion = scripts.KclAbiVersion
```
-## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L167)
+## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L156)
```go
func FormatCode(code interface{}) ([]byte, error)
@@ -203,7 +137,7 @@ a = 1 + 2
-## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L179)
+## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L168)
```go
func FormatPath(path string) (changedPaths []string, err error)
@@ -238,7 +172,7 @@ func main() {
-## func [GetSchemaTypeMapping](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L258)
+## func [GetSchemaTypeMapping](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L247)
```go
func GetSchemaTypeMapping(filename string, src any, schemaName string) (map[string]*KclType, error)
@@ -264,23 +198,8 @@ schema_name: string
The schema name got, when the schema name is empty, all schemas are returned.
```
-## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L75)
-```go
-func InitKclvmPath(kclvmRoot string)
-```
-
-InitKclvmPath init kclvm path.
-
-## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L80)
-
-```go
-func InitKclvmRuntime(n int)
-```
-
-InitKclvmRuntime init kclvm process.
-
-## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L199)
+## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L188)
```go
func LintPath(paths []string) (results []string, err error)
@@ -325,7 +244,7 @@ Module 'a' imported but unused
-## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L184)
+## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L173)
```go
func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error)
@@ -333,7 +252,7 @@ func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err
ListDepFiles return the depend files from the given path
-## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L194)
+## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L183)
```go
func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error)
@@ -341,7 +260,7 @@ func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error)
ListDownStreamFiles return a list of downstream depend files from the given changed path list.
-## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L189)
+## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L178)
```go
func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error)
@@ -349,7 +268,7 @@ func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err
ListUpStreamFiles return a list of upstream depend files from the given path list
-## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L208)
+## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L197)
```go
func OverrideFile(file string, specs, importPaths []string) (bool, error)
@@ -357,7 +276,7 @@ func OverrideFile(file string, specs, importPaths []string) (bool, error)
OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. importPaths. List of import statements that need to be added. See https://www.kcl-lang.io/docs/user_docs/guides/automation for more override spec guide.
-## func [Validate](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L219)
+## func [Validate](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L208)
```go
func Validate(dataFile, schemaFile string, opts *ValidateOptions) (ok bool, err error)
@@ -365,7 +284,7 @@ func Validate(dataFile, schemaFile string, opts *ValidateOptions) (ok bool, err
Validate validates the given data file against the specified schema file with the provided options.
-## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L213)
+## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L202)
```go
func ValidateCode(data, code string, opts *ValidateOptions) (ok bool, err error)
@@ -373,7 +292,7 @@ func ValidateCode(data, code string, opts *ValidateOptions) (ok bool, err error)
ValidateCode validate data string match code string
-## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L57)
+## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L56)
```go
type KCLResult = kcl.KCLResult
@@ -467,13 +386,13 @@ person: {Name:kcl Age:101}
-## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L58)
+## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L57)
```go
type KCLResultList = kcl.KCLResultList
```
-### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85)
+### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L74)
```go
func MustRun(path string, opts ...Option) *KCLResultList
@@ -600,7 +519,7 @@ func main() {
-### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L90)
+### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L79)
```go
func Run(path string, opts ...Option) (*KCLResultList, error)
@@ -608,7 +527,7 @@ func Run(path string, opts ...Option) (*KCLResultList, error)
Run evaluates the KCL program with path and opts, then returns the object list.
-### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L95)
+### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L84)
```go
func RunFiles(paths []string, opts ...Option) (*KCLResultList, error)
@@ -637,13 +556,13 @@ func main() {
-## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L60)
+## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L59)
```go
type KclType = kcl.KclType
```
-### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L241)
+### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L230)
```go
func GetSchemaType(filename string, src any, schemaName string) ([]*KclType, error)
@@ -669,31 +588,31 @@ schema_name: string
The schema name got, when the schema name is empty, all schemas are returned.
```
-## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L52)
+## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L51)
```go
type ListDepFilesOption = list.Option
```
-## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L51)
+## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L50)
```go
type ListDepsOptions = list.DepOptions
```
-## type [ListOptionsArgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L68)
+## type [ListOptionsArgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L67)
```go
type ListOptionsArgs = loader.ListOptionsArgs
```
-## type [ListOptionsResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69)
+## type [ListOptionsResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L68)
```go
type ListOptionsResult = loader.ListOptionsResult
```
-### func [ListOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L280)
+### func [ListOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L269)
```go
func ListOptions(args *ListOptionsArgs) (*ListOptionsResult, error)
@@ -722,30 +641,25 @@ func main() {
log.Fatal(err)
}
fmt.Println(result)
-
}
```
-```
-options:{name:"key1"} options:{name:"key2" required:true} options:{name:"metadata-key"}
-```
-
-## type [ListVariablesArgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L66)
+## type [ListVariablesArgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L65)
```go
type ListVariablesArgs = loader.ListVariablesArgs
```
-## type [ListVariablesResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L67)
+## type [ListVariablesResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L66)
```go
type ListVariablesResult = loader.ListVariablesResult
```
-### func [ListVariables](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L274)
+### func [ListVariables](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L263)
```go
func ListVariables(args *ListVariablesArgs) (*ListVariablesResult, error)
@@ -774,7 +688,6 @@ func main() {
log.Fatal(err)
}
fmt.Println(result)
-
}
```
@@ -785,19 +698,19 @@ variables:{key:"age" value:{variables:{value:"2" op_sym:"="}}} variables:{key
-## type [LoadPackageArgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64)
+## type [LoadPackageArgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L63)
```go
type LoadPackageArgs = loader.LoadPackageArgs
```
-## type [LoadPackageResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L65)
+## type [LoadPackageResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L64)
```go
type LoadPackageResult = loader.LoadPackageResult
```
-### func [LoadPackage](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L269)
+### func [LoadPackage](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L258)
```go
func LoadPackage(args *LoadPackageArgs) (*LoadPackageResult, error)
@@ -835,13 +748,13 @@ func main() {
-## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50)
+## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L49)
```go
type Option = kcl.Option
```
-### func [NewOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100)
+### func [NewOption](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L89)
```go
func NewOption() *Option
@@ -849,7 +762,7 @@ func NewOption() *Option
NewOption returns a new Option.
-### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105)
+### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L94)
```go
func WithCode(codes ...string) Option
@@ -857,7 +770,7 @@ func WithCode(codes ...string) Option
WithCode returns a Option which hold a kcl source code list.
-### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L134)
+### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L123)
```go
func WithDisableNone(disableNone bool) Option
@@ -865,7 +778,7 @@ func WithDisableNone(disableNone bool) Option
WithDisableNone returns a Option which hold a disable none switch.
-### func [WithExternalPkgAndPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L111)
+### func [WithExternalPkgAndPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L100)
```go
func WithExternalPkgAndPath(name, path string) Option
@@ -873,7 +786,7 @@ func WithExternalPkgAndPath(name, path string) Option
WithExternalPkgAndPath returns a Option which hold a external package.
-### func [WithExternalPkgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L108)
+### func [WithExternalPkgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L97)
```go
func WithExternalPkgs(externalPkgs ...string) Option
@@ -881,7 +794,7 @@ func WithExternalPkgs(externalPkgs ...string) Option
WithExternalPkgs returns a Option which hold a external package list.
-### func [WithFullTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142)
+### func [WithFullTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L131)
```go
func WithFullTypePath(fullTypePath bool) Option
@@ -889,7 +802,7 @@ func WithFullTypePath(fullTypePath bool) Option
WithFullTypePath returns a Option which hold a include full type string in the \`\_type\` attribute.
-### func [WithIncludeSchemaTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137)
+### func [WithIncludeSchemaTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L126)
```go
func WithIncludeSchemaTypePath(includeSchemaTypePath bool) Option
@@ -897,7 +810,7 @@ func WithIncludeSchemaTypePath(includeSchemaTypePath bool) Option
WithIncludeSchemaTypePath returns a Option which hold a include schema type path switch.
-### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L116)
+### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L105)
```go
func WithKFilenames(filenames ...string) Option
@@ -905,7 +818,7 @@ func WithKFilenames(filenames ...string) Option
WithKFilenames returns a Option which hold a filenames list.
-### func [WithLogger](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L162)
+### func [WithLogger](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L151)
```go
func WithLogger(l io.Writer) Option
@@ -913,7 +826,7 @@ func WithLogger(l io.Writer) Option
WithLogger returns a Option which hold a logger.
-### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L119)
+### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L108)
```go
func WithOptions(key_value_list ...string) Option
@@ -959,7 +872,7 @@ name: kcl
-### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122)
+### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L111)
```go
func WithOverrides(override_list ...string) Option
@@ -967,7 +880,7 @@ func WithOverrides(override_list ...string) Option
WithOverrides returns a Option which hold a override list.
-### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L147)
+### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L136)
```go
func WithPrintOverridesAST(printOverridesAST bool) Option
@@ -975,7 +888,7 @@ func WithPrintOverridesAST(printOverridesAST bool) Option
WithPrintOverridesAST returns a Option which hold a printOverridesAST switch.
-### func [WithSelectors](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L125)
+### func [WithSelectors](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L114)
```go
func WithSelectors(selectors ...string) Option
@@ -983,7 +896,7 @@ func WithSelectors(selectors ...string) Option
WithSelectors returns a Option which hold a path selector list.
-### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L128)
+### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L117)
```go
func WithSettings(filename string) Option
@@ -991,7 +904,7 @@ func WithSettings(filename string) Option
WithSettings returns a Option which hold a settings file.
-### func [WithShowHidden](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L157)
+### func [WithShowHidden](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L146)
```go
func WithShowHidden(showHidden bool) Option
@@ -999,7 +912,7 @@ func WithShowHidden(showHidden bool) Option
WithShowHidden returns a Option which holds a showHidden switch.
-### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L152)
+### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L141)
```go
func WithSortKeys(sortKeys bool) Option
@@ -1007,7 +920,7 @@ func WithSortKeys(sortKeys bool) Option
WithSortKeys returns a Option which holds a sortKeys switch.
-### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L131)
+### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L120)
```go
func WithWorkDir(workDir string) Option
@@ -1015,19 +928,19 @@ func WithWorkDir(workDir string) Option
WithWorkDir returns a Option which hold a work dir.
-## type [ParseProgramArgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L70)
+## type [ParseProgramArgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L69)
```go
type ParseProgramArgs = parser.ParseProgramArgs
```
-## type [ParseProgramResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L71)
+## type [ParseProgramResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L70)
```go
type ParseProgramResult = parser.ParseProgramResult
```
-### func [ParseProgram](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L263)
+### func [ParseProgram](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L252)
```go
func ParseProgram(args *ParseProgramArgs) (*ParseProgramResult, error)
@@ -1062,25 +975,25 @@ func main() {
-## type [TestCaseInfo](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L55)
+## type [TestCaseInfo](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L54)
```go
type TestCaseInfo = testing.TestCaseInfo
```
-## type [TestOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54)
+## type [TestOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L53)
```go
type TestOptions = testing.TestOptions
```
-## type [TestResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L56)
+## type [TestResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L55)
```go
type TestResult = testing.TestResult
```
-### func [Test](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L224)
+### func [Test](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L213)
```go
func Test(testOpts *TestOptions, opts ...Option) (TestResult, error)
@@ -1088,19 +1001,19 @@ func Test(testOpts *TestOptions, opts ...Option) (TestResult, error)
Test calls the test tool to run uni tests in packages.
-## type [UpdateDependenciesArgs](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L62)
+## type [UpdateDependenciesArgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L61)
```go
type UpdateDependenciesArgs = module.UpdateDependenciesArgs
```
-## type [UpdateDependenciesResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L63)
+## type [UpdateDependenciesResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L62)
```go
type UpdateDependenciesResult = module.UpdateDependenciesResult
```
-### func [UpdateDependencies](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L285)
+### func [UpdateDependencies](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L274)
```go
func UpdateDependencies(args *UpdateDependenciesArgs) (*UpdateDependenciesResult, error)
@@ -1132,7 +1045,7 @@ func main() {
// helloworld = { oci = "oci://ghcr.io/kcl-lang/helloworld", tag = "0.1.0" }
// flask = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests", commit = "ade147b" }
- result, err := kcl.UpdateDependencies(&gpyrpc.UpdateDependencies_Args{
+ result, err := kcl.UpdateDependencies(&gpyrpc.UpdateDependenciesArgs{
ManifestPath: "testdata/update_dependencies",
})
if err != nil {
@@ -1156,7 +1069,7 @@ import (
"fmt"
"log"
- kcl "kcl-lang.io/kcl-go"
+ "kcl-lang.io/kcl-go/pkg/native"
"kcl-lang.io/kcl-go/pkg/spec/gpyrpc"
)
@@ -1170,7 +1083,9 @@ func main() {
// helloworld = { oci = "oci://ghcr.io/kcl-lang/helloworld", tag = "0.1.0" }
// flask = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests", commit = "ade147b" }
- result, err := kcl.UpdateDependencies(&gpyrpc.UpdateDependencies_Args{
+ svc := native.NewNativeServiceClient()
+
+ result, err := svc.UpdateDependencies(&gpyrpc.UpdateDependenciesArgs{
ManifestPath: "testdata/update_dependencies",
})
if err != nil {
@@ -1182,15 +1097,15 @@ func main() {
// a = helloworld.The_first_kcl_program
// fmt.Println(result.ExternalPkgs)
- opt := kcl.NewOption()
- opt.ExternalPkgs = result.ExternalPkgs
-
- runResult, err := kcl.Run("testdata/update_dependencies/main.k", *opt)
+ execResult, err := svc.ExecProgram(&gpyrpc.ExecProgramArgs{
+ KFilenameList: []string{"testdata/update_dependencies/main.k"},
+ ExternalPkgs: result.ExternalPkgs,
+ })
if err != nil {
log.Fatal(err)
}
- fmt.Println(runResult.GetRawYamlResult())
+ fmt.Println(execResult.YamlResult)
}
```
@@ -1202,19 +1117,19 @@ a: Hello World!
-## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L53)
+## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L52)
```go
type ValidateOptions = validate.ValidateOptions
```
-## type [VersionResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L61)
+## type [VersionResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L60)
```go
type VersionResult = kcl.VersionResult
```
-### func [GetVersion](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L290)
+### func [GetVersion](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L279)
```go
func GetVersion() (*VersionResult, error)
diff --git a/docs/reference/xlang-api/java-api.md b/docs/reference/xlang-api/java-api.md
index f7bc34633..f7d24658a 100644
--- a/docs/reference/xlang-api/java-api.md
+++ b/docs/reference/xlang-api/java-api.md
@@ -30,7 +30,7 @@ This way you'll be able to import the above dependency to use the SDK.
com.kclkcl-lib
- 0.10.8-SNAPSHOT
+ 0.12.1
```
@@ -38,14 +38,14 @@ This way you'll be able to import the above dependency to use the SDK.
```java
import com.kcl.api.API;
-import com.kcl.api.Spec.ExecProgram_Args;
-import com.kcl.api.Spec.ExecProgram_Result;
+import com.kcl.api.Spec.ExecProgramArgs;
+import com.kcl.api.Spec.ExecProgramResult;
public class ExecProgramTest {
public static void main(String[] args) throws Exception {
API api = new API();
- ExecProgram_Result result = api
- .execProgram(ExecProgram_Args.newBuilder().addKFilenameList("path/to/kcl.k").build());
+ ExecProgramResult result = api
+ .execProgram(ExecProgramArgs.newBuilder().addKFilenameList("path/to/kcl.k").build());
System.out.println(result.getYamlResult());
}
}
@@ -76,9 +76,9 @@ Java Code
```java
import com.kcl.api.*;
-ExecProgram_Args args = ExecProgram_Args.newBuilder().addKFilenameList("schema.k").build();
+ExecProgramArgs args = ExecProgramArgs.newBuilder().addKFilenameList("schema.k").build();
API apiInstance = new API();
-ExecProgram_Result result = apiInstance.execProgram(args);
+ExecProgramResult result = apiInstance.execProgram(args);
```
@@ -107,9 +107,9 @@ Java Code
```java
import com.kcl.api.*;
-ParseFile_Args args = ParseFile_Args.newBuilder().setPath("schema.k").build();
+ParseFileArgs args = ParseFileArgs.newBuilder().setPath("schema.k").build();
API apiInstance = new API();
-ParseFile_Result result = apiInstance.parseFile(args);
+ParseFileResult result = apiInstance.parseFile(args);
```
@@ -141,8 +141,8 @@ import com.kcl.ast.*;
import com.kcl.util.JsonUtil;
API api = new API();
-ParseProgram_Result result = api.parseProgram(
- ParseProgram_Args.newBuilder().addPaths("path/to/kcl.k").build()
+ParseProgramResult result = api.parseProgram(
+ ParseProgramArgs.newBuilder().addPaths("path/to/kcl.k").build()
);
System.out.println(result.getAstJson());
Program program = JsonUtil.deserializeProgram(result.getAstJson());
@@ -175,9 +175,9 @@ Java Code
import com.kcl.api.*;
API api = new API();
-LoadPackage_Result result = api.loadPackage(LoadPackage_Args.newBuilder().setResolveAst(true)
+LoadPackageResult result = api.loadPackage(LoadPackageArgs.newBuilder().setResolveAst(true)
.setWithAstIndex(true)
- .setParseArgs(ParseProgram_Args.newBuilder().addPaths("schema.k").build()).build());
+ .setParseArgs(ParseProgramArgs.newBuilder().addPaths("schema.k").build()).build());
```
@@ -207,9 +207,9 @@ Java Code
import com.kcl.api.*;
API api = new API();
-ListVariables_Result result = api.listVariables(
- ListVariables_Args.newBuilder().setResolveAst(true).setParseArgs(
- ParseProgram_Args.newBuilder().addPaths("/path/to/kcl.k").build())
+ListVariablesResult result = api.listVariables(
+ ListVariablesArgs.newBuilder().setResolveAst(true).setParseArgs(
+ ParseProgramArgs.newBuilder().addPaths("/path/to/kcl.k").build())
.build());
result.getSymbolsMap().values().forEach(s -> System.out.println(s));
```
@@ -239,9 +239,9 @@ Java Code
```java
import com.kcl.api.*;
-ParseProgram_Args args = ParseProgram_Args.newBuilder().addPaths("./src/test_data/option/main.k").build();
+ParseProgramArgs args = ParseProgramArgs.newBuilder().addPaths("./src/test_data/option/main.k").build();
API apiInstance = new API();
-ListOptions_Result result = apiInstance.listOptions(args);
+ListOptionsResult result = apiInstance.listOptions(args);
```
@@ -270,10 +270,10 @@ Java Code
```java
import com.kcl.api.*;
-ExecProgram_Args execArgs = ExecProgram_Args.newBuilder().addKFilenameList("schema.k").build();
-GetSchemaTypeMapping_Args args = GetSchemaTypeMapping_Args.newBuilder().setExecArgs(execArgs).build();
+ExecProgramArgs execArgs = ExecProgramArgs.newBuilder().addKFilenameList("schema.k").build();
+GetSchemaTypeMappingArgs args = GetSchemaTypeMappingArgs.newBuilder().setExecArgs(execArgs).build();
API apiInstance = new API();
-GetSchemaTypeMapping_Result result = apiInstance.getSchemaTypeMapping(args);
+GetSchemaTypeMappingResult result = apiInstance.getSchemaTypeMapping(args);
KclType appSchemaType = result.getSchemaTypeMappingMap().get("app");
String replicasType = appSchemaType.getPropertiesOrThrow("replicas").getType();
```
@@ -306,7 +306,7 @@ import com.kcl.api.*;
API api = new API();
String spec = "a=2";
-OverrideFile_Result result = api.overrideFile(OverrideFile_Args.newBuilder()
+OverrideFileResult result = api.overrideFile(OverrideFileArgs.newBuilder()
.setFile("./src/test_data/override_file/main.k").addSpecs(spec).build());
```
@@ -327,9 +327,9 @@ import com.kcl.api.*;
String sourceCode = "schema Person:\n" + " name: str\n" + " age: int\n" + " check:\n"
+ " 0 < age < 120\n";
-FormatCode_Args args = FormatCode_Args.newBuilder().setSource(sourceCode).build();
+FormatCodeArgs args = FormatCodeArgs.newBuilder().setSource(sourceCode).build();
API apiInstance = new API();
-FormatCode_Result result = apiInstance.formatCode(args);
+FormatCodeResult result = apiInstance.formatCode(args);
String expectedFormattedCode = "schema Person:\n" + " name: str\n" + " age: int\n\n" + " check:\n"
+ " 0 < age < 120\n\n";
```
@@ -360,9 +360,9 @@ Java Code
```java
import com.kcl.api.*;
-FormatPath_Args args = FormatPath_Args.newBuilder().setPath("format_path.k").build();
+FormatPathArgs args = FormatPathArgs.newBuilder().setPath("format_path.k").build();
API apiInstance = new API();
-FormatPath_Result result = apiInstance.formatPath(args);
+FormatPathResult result = apiInstance.formatPath(args);
Assert.assertTrue(result.getChangedPathsList().isEmpty());
```
@@ -389,9 +389,9 @@ Java Code
```java
import com.kcl.api.*;
-LintPath_Args args = LintPath_Args.newBuilder().addPaths("lint_path.k").build();
+LintPathArgs args = LintPathArgs.newBuilder().addPaths("lint_path.k").build();
API apiInstance = new API();
-LintPath_Result result = apiInstance.lintPath(args);
+LintPathResult result = apiInstance.lintPath(args);
boolean foundWarning = result.getResultsList().stream()
.anyMatch(warning -> warning.contains("Module 'math' imported but unused"));
```
@@ -414,9 +414,9 @@ import com.kcl.api.*;
String code = "schema Person:\n" + " name: str\n" + " age: int\n" + " check:\n"
+ " 0 < age < 120\n";
String data = "{\"name\": \"Alice\", \"age\": 10}";
-ValidateCode_Args args = ValidateCode_Args.newBuilder().setCode(code).setData(data).setFormat("json").build();
+ValidateCodeArgs args = ValidateCodeArgs.newBuilder().setCode(code).setData(data).setFormat("json").build();
API apiInstance = new API();
-ValidateCode_Result result = apiInstance.validateCode(args);
+ValidateCodeResult result = apiInstance.validateCode(args);
```
@@ -441,10 +441,10 @@ Java Code
```java
import com.kcl.api.*;
-Rename_Args args = Rename_Args.newBuilder().setPackageRoot(".").setSymbolPath("a")
+RenameArgs args = RenameArgs.newBuilder().setPackageRoot(".").setSymbolPath("a")
.addFilePaths("main.k").setNewName("a2").build();
API apiInstance = new API();
-Rename_Result result = apiInstance.rename(args);
+RenameResult result = apiInstance.rename(args);
```
@@ -463,9 +463,9 @@ Java Code
import com.kcl.api.*;
API api = new API();
-RenameCode_Args args = RenameCode_Args.newBuilder().setPackageRoot("/mock/path").setSymbolPath("a")
+RenameCodeArgs args = RenameCodeArgs.newBuilder().setPackageRoot("/mock/path").setSymbolPath("a")
.putSourceCodes("/mock/path/main.k", "a = 1\nb = a").setNewName("a2").build();
-RenameCode_Result result = api.renameCode(args);
+RenameCodeResult result = api.renameCode(args);
```
@@ -484,8 +484,8 @@ Java Code
import com.kcl.api.*;
API apiInstance = new API();
-Test_Args args = Test_Args.newBuilder().addPkgList("/path/to/test/package").build();
-Test_Result result = apiInstance.test(args);
+TestArgs args = TestArgs.newBuilder().addPkgList("/path/to/test/package").build();
+TestResult result = apiInstance.test(args);
```
@@ -514,9 +514,9 @@ Java Code
import com.kcl.api.*;
API api = new API();
-LoadSettingsFiles_Args args = LoadSettingsFiles_Args.newBuilder().addFiles("kcl.yaml")
+LoadSettingsFilesArgs args = LoadSettingsFilesArgs.newBuilder().addFiles("kcl.yaml")
.build();
-LoadSettingsFiles_Result result = api.loadSettingsFiles(args);
+LoadSettingsFilesResult result = api.loadSettingsFiles(args);
```
@@ -549,8 +549,8 @@ import com.kcl.api.*;
API api = new API();
-UpdateDependencies_Result result = api.updateDependencies(
- UpdateDependencies_Args.newBuilder().setManifestPath("module").build());
+UpdateDependenciesResult result = api.updateDependencies(
+ UpdateDependenciesArgs.newBuilder().setManifestPath("module").build());
```
@@ -590,13 +590,13 @@ import com.kcl.api.*;
API api = new API();
-UpdateDependencies_Result result = api.updateDependencies(
- UpdateDependencies_Args.newBuilder().setManifestPath("./src/test_data/update_dependencies").build());
+UpdateDependenciesResult result = api.updateDependencies(
+ UpdateDependenciesArgs.newBuilder().setManifestPath("./src/test_data/update_dependencies").build());
-ExecProgram_Args execArgs = ExecProgram_Args.newBuilder(). addAllExternalPkgs(result.getExternalPkgsList())
+ExecProgramArgs execArgs = ExecProgramArgs.newBuilder(). addAllExternalPkgs(result.getExternalPkgsList())
.addKFilenameList("./src/test_data/update_dependencies/main.k").build();
-ExecProgram_Result execResult = api.execProgram(execArgs);
+ExecProgramResult execResult = api.execProgram(execArgs);
```
@@ -615,8 +615,8 @@ Java Code
import com.kcl.api.*;
API api = new API();
-GetVersion_Args version_args = GetVersion_Args.newBuilder().build();
-GetVersion_Result result = api.getVersion(version_args);
+GetVersionArgs version_args = GetVersionArgs.newBuilder().build();
+GetVersionResult result = api.getVersion(version_args);
```
diff --git a/docs/reference/xlang-api/kotlin-api.md b/docs/reference/xlang-api/kotlin-api.md
index c418127f7..4403b1097 100644
--- a/docs/reference/xlang-api/kotlin-api.md
+++ b/docs/reference/xlang-api/kotlin-api.md
@@ -30,7 +30,7 @@ This way you'll be able to import the above dependency to use the SDK.
com.kclkcl-lib-kotlin
- 0.10.8-SNAPSHOT
+ 0.12.1
```
diff --git a/docs/reference/xlang-api/overview.md b/docs/reference/xlang-api/overview.md
index 21cbfb736..8ce491ae2 100644
--- a/docs/reference/xlang-api/overview.md
+++ b/docs/reference/xlang-api/overview.md
@@ -47,30 +47,30 @@ The complete `BuiltinService` is defined by Protobuf:
```protobuf
service BuiltinService {
- rpc Ping(Ping_Args) returns(Ping_Result);
- rpc ListMethod(ListMethod_Args) returns(ListMethod_Result);
+ rpc Ping(PingArgs) returns(PingResult);
+ rpc ListMethod(ListMethodArgs) returns(ListMethodResult);
}
-message Ping_Args {
+message PingArgs {
string value = 1;
}
-message Ping_Result {
+message PingResult {
string value = 1;
}
-message ListMethod_Args {
+message ListMethodArgs {
// empty
}
-message ListMethod_Result {
+message ListMethodResult {
repeated string method_name_list = 1;
}
```
The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided.
-### `KclvmService`
+### `KclService`
-The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service.
+The `KclService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service.
For example, there is the following `Person` structure definition:
@@ -88,10 +88,10 @@ Then we want to use `Person` to verify the following JSON data:
{ "key": "value" }
```
-This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method:
+This can be done through the `ValidateCode` method of the `KclService` service. Refer to the `ValidateCodeArgs` structure of the `ValidateCode` method:
```protobuf
-message ValidateCode_Args {
+message ValidateCodeArgs {
string data = 1;
string code = 2;
string schema = 3;
@@ -100,7 +100,7 @@ message ValidateCode_Args {
}
```
-Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified:
+Construct the JSON data required by the POST request according to the `ValidateCodeArgs` structure, which contains the `Person` definition and the JSON data to be verified:
```json
{
@@ -113,7 +113,7 @@ Save this JSON data to the `vet-hello.json` file and verify it with the followin
```shell
$ curl -X POST \
- http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \
+ http://127.0.0.1:2021/api:protorpc/KclService.ValidateCode \
-H "accept: application/json" \
--data @./vet-hello.json
{
diff --git a/docs/reference/xlang-api/python-api.md b/docs/reference/xlang-api/python-api.md
index 5137d13f7..c8d7064ad 100644
--- a/docs/reference/xlang-api/python-api.md
+++ b/docs/reference/xlang-api/python-api.md
@@ -15,7 +15,7 @@ python3 -m pip install kcl-lib
```typescript
import kcl_lib.api as api
-args = api.ExecProgram_Args(k_filename_list=["path/to/kcl.k"])
+args = api.ExecProgramArgs(k_filename_list=["path/to/kcl.k"])
api = api.API()
result = api.exec_program(args)
print(result.yaml_result)
@@ -46,7 +46,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.ExecProgram_Args(k_filename_list=["schema.k"])
+args = api.ExecProgramArgs(k_filename_list=["schema.k"])
api = api.API()
result = api.exec_program(args)
assert result.yaml_result == "app:\n replicas: 2"
@@ -64,7 +64,7 @@ A case with the file not found error
import kcl_lib.api as api
try:
- args = api.ExecProgram_Args(k_filename_list=["file_not_found"])
+ args = api.ExecProgramArgs(k_filename_list=["file_not_found"])
api = api.API()
result = api.exec_program(args)
assert False
@@ -98,7 +98,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.ParseFile_Args(path=TEST_FILE)
+args = api.ParseFileArgs(path=TEST_FILE)
api = api.API()
result = api.parse_file(args)
assert len(result.errors) == 0
@@ -130,7 +130,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.ParseProgram_Args(paths=["schema.k"])
+args = api.ParseProgramArgs(paths=["schema.k"])
api = api.API()
result = api.parse_program(args)
assert len(result.paths) == 1
@@ -163,8 +163,8 @@ Python Code
```python
import kcl_lib.api as api
-args = api.LoadPackage_Args(
- parse_args=api.ParseProgram_Args(paths=["schema.k"]), resolve_ast=True
+args = api.LoadPackageArgs(
+ parse_args=api.ParseProgramArgs(paths=["schema.k"]), resolve_ast=True
)
api = api.API()
result = api.load_package(args)
@@ -197,7 +197,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.ListVariables_Args(files=[TEST_FILE])
+args = api.ListVariablesArgs(files=[TEST_FILE])
api = api.API()
result = api.list_variables(args)
assert result.variables["app"].variables[0].value == "AppConfig {replicas: 2}"
@@ -228,7 +228,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.ParseProgram_Args(paths=["options.k"])
+args = api.ParseProgramArgs(paths=["options.k"])
api = api.API()
result = api.list_options(args)
assert len(result.options) == 3
@@ -263,8 +263,8 @@ Python Code
```python
import kcl_lib.api as api
-exec_args = api.ExecProgram_Args(k_filename_list=["schema.k"])
-args = api.GetSchemaTypeMapping_Args(exec_args=exec_args)
+exec_args = api.ExecProgramArgs(k_filename_list=["schema.k"])
+args = api.GetSchemaTypeMappingArgs(exec_args=exec_args)
api = api.API()
result = api.get_schema_type_mapping(args)
assert result.schema_type_mapping["app"].properties["replicas"].type == "int"
@@ -298,7 +298,7 @@ import kcl_lib.api as api
import pathlib
test_file = "main.k"
-args = api.OverrideFile_Args(
+args = api.OverrideFileArgs(
file=test_file,
specs=["b.a=2"],
)
@@ -338,7 +338,7 @@ schema Person:
check:
0 < age < 120
"""
-args = api.FormatCode_Args(source=source_code)
+args = api.FormatCodeArgs(source=source_code)
api_instance = api.API()
result = api_instance.format_code(args)
assert (
@@ -381,7 +381,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.FormatPath_Args(path="format_path.k")
+args = api.FormatPathArgs(path="format_path.k")
api_instance = api.API()
result = api_instance.format_path(args)
print(result)
@@ -410,7 +410,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.LintPath_Args(paths=["lint_path.k"])
+args = api.LintPathArgs(paths=["lint_path.k"])
api_instance = api.API()
result = api_instance.lint_path(args)
```
@@ -439,7 +439,7 @@ schema Person:
0 < age < 120
"""
data = '{"name": "Alice", "age": 10}'
-args = api.ValidateCode_Args(code=code, data=data, format="json")
+args = api.ValidateCodeArgs(code=code, data=data, format="json")
api_instance = api.API()
result = api_instance.validate_code(args)
assert result.success == True
@@ -468,7 +468,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.Rename_Args(
+args = api.RenameArgs(
package_root=".",
symbol_path="a",
file_paths=["main.k"],
@@ -493,7 +493,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.RenameCode_Args(
+args = api.RenameCodeArgs(
package_root="/mock/path",
symbol_path="a",
source_codes={"/mock/path/main.k": "a = 1\nb = a"},
@@ -518,7 +518,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.Test_Args(
+args = api.TestArgs(
pkg_list=["path/to/testing/pkg/..."],
)
api_instance = api.API()
@@ -550,7 +550,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.LoadSettingsFiles_Args(
+args = api.LoadSettingsFilesArgs(
work_dir=".", files=["kcl.yaml"]
)
api_instance = api.API()
@@ -590,7 +590,7 @@ Python Code
```python
import kcl_lib.api as api
-args = api.UpdateDependencies_Args(
+args = api.UpdateDependenciesArgs(
manifest_path="module"
)
api_instance = api.API()
@@ -636,12 +636,12 @@ Python Code
```python
import kcl_lib.api as api
-args = api.UpdateDependencies_Args(
+args = api.UpdateDependenciesArgs(
manifest_path="module"
)
api_instance = api.API()
result = api_instance.update_dependencies(args)
-exec_args = api.ExecProgram_Args(
+exec_args = api.ExecProgramArgs(
k_filename_list=["module/main.k"],
external_pkgs=result.external_pkgs,
)
diff --git a/docs/reference/xlang-api/rest-api.md b/docs/reference/xlang-api/rest-api.md
index b9a9ab738..21ab13e1d 100644
--- a/docs/reference/xlang-api/rest-api.md
+++ b/docs/reference/xlang-api/rest-api.md
@@ -32,30 +32,30 @@ The complete `BuiltinService` is defined by Protobuf:
```protobuf
service BuiltinService {
- rpc Ping(Ping_Args) returns(Ping_Result);
- rpc ListMethod(ListMethod_Args) returns(ListMethod_Result);
+ rpc Ping(PingArgs) returns(PingResult);
+ rpc ListMethod(ListMethodArgs) returns(ListMethodResult);
}
-message Ping_Args {
+message PingArgs {
string value = 1;
}
-message Ping_Result {
+message PingResult {
string value = 1;
}
-message ListMethod_Args {
+message ListMethodArgs {
// empty
}
-message ListMethod_Result {
+message ListMethodResult {
repeated string method_name_list = 1;
}
```
The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided.
-## 3. `KclvmService`
+## 3. `KclService`
-The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service.
+The `KclService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service.
For example, there is the following `Person` structure definition:
@@ -73,10 +73,10 @@ Then we want to use `Person` to verify the following JSON data:
{ "key": "value" }
```
-This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method:
+This can be done through the `ValidateCode` method of the `KclService` service. Refer to the `ValidateCodeArgs` structure of the `ValidateCode` method:
```protobuf
-message ValidateCode_Args {
+message ValidateCodeArgs {
string data = 1;
string code = 2;
string schema = 3;
@@ -85,7 +85,7 @@ message ValidateCode_Args {
}
```
-Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified:
+Construct the JSON data required by the POST request according to the `ValidateCodeArgs` structure, which contains the `Person` definition and the JSON data to be verified:
```json
{
@@ -98,7 +98,7 @@ Save this JSON data to the `vet-hello.json` file and verify it with the followin
```shell
$ curl -X POST \
- http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \
+ http://127.0.0.1:2021/api:protorpc/KclService.ValidateCode \
-H "accept: application/json" \
--data @./vet-hello.json
{
@@ -169,14 +169,14 @@ message Message {
// Service for built-in functionality.
service BuiltinService {
// Sends a ping request.
- rpc Ping(Ping_Args) returns (Ping_Result);
+ rpc Ping(PingArgs) returns (PingResult);
// Lists available methods.
- rpc ListMethod(ListMethod_Args) returns (ListMethod_Result);
+ rpc ListMethod(ListMethodArgs) returns (ListMethodResult);
}
// Service for KCL VM interactions.
-service KclvmService {
- /// Ping KclvmService, return the same value as the parameter
+service KclService {
+ /// Ping KclService, return the same value as the parameter
///
/// # Examples
///
@@ -200,9 +200,9 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc Ping(Ping_Args) returns (Ping_Result);
+ rpc Ping(PingArgs) returns (PingResult);
- /// GetVersion KclvmService, return the kclvm service version information
+ /// GetVersion KclService, return the kclvm service version information
///
/// # Examples
///
@@ -227,7 +227,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc GetVersion(GetVersion_Args) returns (GetVersion_Result);
+ rpc GetVersion(GetVersionArgs) returns (GetVersionResult);
/// Parse KCL program with entry files.
///
@@ -255,7 +255,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ParseProgram(ParseProgram_Args) returns (ParseProgram_Result);
+ rpc ParseProgram(ParseProgramArgs) returns (ParseProgramResult);
/// Parse KCL single file to Module AST JSON string with import dependencies
/// and parse errors.
@@ -284,7 +284,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ParseFile(ParseFile_Args) returns (ParseFile_Result);
+ rpc ParseFile(ParseFileArgs) returns (ParseFileResult);
/// load_package provides users with the ability to parse kcl program and semantic model
/// information including symbols, types, definitions, etc.
@@ -323,7 +323,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc LoadPackage(LoadPackage_Args) returns (LoadPackage_Result);
+ rpc LoadPackage(LoadPackageArgs) returns (LoadPackageResult);
/// list_options provides users with the ability to parse kcl program and get all option information.
///
@@ -353,7 +353,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ListOptions(ParseProgram_Args) returns (ListOptions_Result);
+ rpc ListOptions(ParseProgramArgs) returns (ListOptionsResult);
/// list_variables provides users with the ability to parse kcl program and get all variables by specs.
///
@@ -388,7 +388,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ListVariables(ListVariables_Args) returns (ListVariables_Result);
+ rpc ListVariables(ListVariablesArgs) returns (ListVariablesResult);
/// Execute KCL file with args. **Note that it is not thread safe.**
///
@@ -481,7 +481,7 @@ service KclvmService {
/// "id": 4
/// }
/// ```
- rpc ExecProgram(ExecProgram_Args) returns (ExecProgram_Result);
+ rpc ExecProgram(ExecProgramArgs) returns (ExecProgramResult);
/// Build the KCL program to an artifact.
///
@@ -511,7 +511,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc BuildProgram(BuildProgram_Args) returns (BuildProgram_Result);
+ rpc BuildProgram(BuildProgramArgs) returns (BuildProgramResult);
/// Execute the KCL artifact with args. **Note that it is not thread safe.**
///
@@ -544,7 +544,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ExecArtifact(ExecArtifact_Args) returns (ExecProgram_Result);
+ rpc ExecArtifact(ExecArtifactArgs) returns (ExecProgramResult);
/// Override KCL file with args.
///
@@ -572,7 +572,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result);
+ rpc OverrideFile(OverrideFileArgs) returns (OverrideFileResult);
/// Get schema type mapping.
///
@@ -619,7 +619,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns (GetSchemaTypeMapping_Result);
+ rpc GetSchemaTypeMapping(GetSchemaTypeMappingArgs) returns (GetSchemaTypeMappingResult);
/// Format code source.
///
@@ -645,7 +645,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc FormatCode(FormatCode_Args) returns (FormatCode_Result);
+ rpc FormatCode(FormatCodeArgs) returns (FormatCodeResult);
/// Format KCL file or directory path contains KCL files and returns the changed file paths.
///
@@ -671,7 +671,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc FormatPath(FormatPath_Args) returns (FormatPath_Result);
+ rpc FormatPath(FormatPathArgs) returns (FormatPathResult);
/// Lint files and return error messages including errors and warnings.
///
@@ -697,7 +697,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc LintPath(LintPath_Args) returns (LintPath_Result);
+ rpc LintPath(LintPathArgs) returns (LintPathResult);
/// Validate code using schema and data strings.
///
@@ -727,9 +727,9 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc ValidateCode(ValidateCode_Args) returns (ValidateCode_Result);
+ rpc ValidateCode(ValidateCodeArgs) returns (ValidateCodeResult);
- rpc ListDepFiles(ListDepFiles_Args) returns (ListDepFiles_Result);
+ rpc ListDepFiles(ListDepFilesArgs) returns (ListDepFilesResult);
/// Build setting file config from args.
///
/// # Examples
@@ -769,7 +769,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns (LoadSettingsFiles_Result);
+ rpc LoadSettingsFiles(LoadSettingsFilesArgs) returns (LoadSettingsFilesResult);
/// Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed.
/// Return the file paths that got changed.
@@ -799,7 +799,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc Rename(Rename_Args) returns (Rename_Result);
+ rpc Rename(RenameArgs) returns (RenameResult);
/// Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
///
@@ -832,7 +832,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc RenameCode(RenameCode_Args) returns (RenameCode_Result);
+ rpc RenameCode(RenameCodeArgs) returns (RenameCodeResult);
/// Test KCL packages with test arguments.
///
@@ -861,7 +861,7 @@ service KclvmService {
/// "id": 1
/// }
/// ```
- rpc Test(Test_Args) returns (Test_Result);
+ rpc Test(TestArgs) returns (TestResult);
/// Download and update dependencies defined in the kcl.mod file.
///
@@ -911,28 +911,28 @@ service KclvmService {
/// "id": 2
/// }
/// ```
- rpc UpdateDependencies(UpdateDependencies_Args) returns (UpdateDependencies_Result);
+ rpc UpdateDependencies(UpdateDependenciesArgs) returns (UpdateDependenciesResult);
}
// Message for ping request arguments.
-message Ping_Args {
+message PingArgs {
// Value to be sent in the ping request.
string value = 1;
}
// Message for ping response.
-message Ping_Result {
+message PingResult {
// Value received in the ping response.
string value = 1;
}
// Message for version request arguments. Empty message.
-message GetVersion_Args {
+message GetVersionArgs {
// empty
}
// Message for version response.
-message GetVersion_Result {
+message GetVersionResult {
// KCL version.
string version = 1;
// Checksum of the KCL version.
@@ -944,18 +944,18 @@ message GetVersion_Result {
}
// Message for list method request arguments. Empty message.
-message ListMethod_Args {
+message ListMethodArgs {
// empty
}
// Message for list method response.
-message ListMethod_Result {
+message ListMethodResult {
// List of available method names.
repeated string method_name_list = 1;
}
// Message for parse file request arguments.
-message ParseFile_Args {
+message ParseFileArgs {
// Path of the file to be parsed.
string path = 1;
// Source code to be parsed.
@@ -965,7 +965,7 @@ message ParseFile_Args {
}
// Message for parse file response.
-message ParseFile_Result {
+message ParseFileResult {
// Abstract Syntax Tree (AST) in JSON format.
string ast_json = 1;
// File dependency paths.
@@ -975,7 +975,7 @@ message ParseFile_Result {
}
// Message for parse program request arguments.
-message ParseProgram_Args {
+message ParseProgramArgs {
// Paths of the program files to be parsed.
repeated string paths = 1;
// Source codes to be parsed.
@@ -985,7 +985,7 @@ message ParseProgram_Args {
}
// Message for parse program response.
-message ParseProgram_Result {
+message ParseProgramResult {
// Abstract Syntax Tree (AST) in JSON format.
string ast_json = 1;
// Returns the files in the order they should be compiled.
@@ -995,9 +995,9 @@ message ParseProgram_Result {
}
// Message for load package request arguments.
-message LoadPackage_Args {
+message LoadPackageArgs {
// Arguments for parsing the program.
- ParseProgram_Args parse_args = 1;
+ ParseProgramArgs parse_args = 1;
// Flag indicating whether to resolve AST.
bool resolve_ast = 2;
// Flag indicating whether to load built-in modules.
@@ -1007,7 +1007,7 @@ message LoadPackage_Args {
}
// Message for load package response.
-message LoadPackage_Result {
+message LoadPackageResult {
// Program Abstract Syntax Tree (AST) in JSON format.
string program = 1;
// Returns the files in the order they should be compiled.
@@ -1031,7 +1031,7 @@ message LoadPackage_Result {
}
// Message for list options response.
-message ListOptions_Result {
+message ListOptionsResult {
// List of available options.
repeated OptionHelp options = 2;
}
@@ -1101,7 +1101,7 @@ message ScopeIndex {
}
// Message for execute program request arguments.
-message ExecProgram_Args {
+message ExecProgramArgs {
// Working directory.
string work_dir = 1;
// List of KCL filenames.
@@ -1141,7 +1141,7 @@ message ExecProgram_Args {
}
// Message for execute program response.
-message ExecProgram_Result {
+message ExecProgramResult {
// Result in JSON format.
string json_result = 1;
// Result in YAML format.
@@ -1153,76 +1153,76 @@ message ExecProgram_Result {
}
// Message for build program request arguments.
-message BuildProgram_Args {
+message BuildProgramArgs {
// Arguments for executing the program.
- ExecProgram_Args exec_args = 1;
+ ExecProgramArgs exec_args = 1;
// Output path.
string output = 2;
}
// Message for build program response.
-message BuildProgram_Result {
+message BuildProgramResult {
// Path of the built program.
string path = 1;
}
// Message for execute artifact request arguments.
-message ExecArtifact_Args {
+message ExecArtifactArgs {
// Path of the artifact.
string path = 1;
// Arguments for executing the program.
- ExecProgram_Args exec_args = 2;
+ ExecProgramArgs exec_args = 2;
}
// Message for reset plugin request arguments.
-message ResetPlugin_Args {
+message ResetPluginArgs {
// Root path for the plugin.
string plugin_root = 1;
}
// Message for reset plugin response. Empty message.
-message ResetPlugin_Result {
+message ResetPluginResult {
// empty
}
// Message for format code request arguments.
-message FormatCode_Args {
+message FormatCodeArgs {
// Source code to be formatted.
string source = 1;
}
// Message for format code response.
-message FormatCode_Result {
+message FormatCodeResult {
// Formatted code as bytes.
bytes formatted = 1;
}
// Message for format file path request arguments.
-message FormatPath_Args {
+message FormatPathArgs {
// Path of the file to format.
string path = 1;
}
// Message for format file path response.
-message FormatPath_Result {
+message FormatPathResult {
// List of changed file paths.
repeated string changed_paths = 1;
}
// Message for lint file path request arguments.
-message LintPath_Args {
+message LintPathArgs {
// Paths of the files to lint.
repeated string paths = 1;
}
// Message for lint file path response.
-message LintPath_Result {
+message LintPathResult {
// List of lint results.
repeated string results = 1;
}
// Message for override file request arguments.
-message OverrideFile_Args {
+message OverrideFileArgs {
// Path of the file to override.
string file = 1;
// List of override specifications.
@@ -1232,7 +1232,7 @@ message OverrideFile_Args {
}
// Message for override file response.
-message OverrideFile_Result {
+message OverrideFileResult {
// Result of the override operation.
bool result = 1;
// List of parse errors encountered.
@@ -1252,7 +1252,7 @@ message VariableList {
}
// Message for list variables request arguments.
-message ListVariables_Args {
+message ListVariablesArgs {
// Files to be processed.
repeated string files = 1;
// Specifications for variables.
@@ -1262,7 +1262,7 @@ message ListVariables_Args {
}
// Message for list variables response.
-message ListVariables_Result {
+message ListVariablesResult {
// Map of variable lists by file.
map variables = 1;
// List of unsupported codes.
@@ -1294,21 +1294,21 @@ message MapEntry {
}
// Message for get schema type mapping request arguments.
-message GetSchemaTypeMapping_Args {
+message GetSchemaTypeMappingArgs {
// Arguments for executing the program.
- ExecProgram_Args exec_args = 1;
+ ExecProgramArgs exec_args = 1;
// Name of the schema.
string schema_name = 2;
}
// Message for get schema type mapping response.
-message GetSchemaTypeMapping_Result {
+message GetSchemaTypeMappingResult {
// Map of schema type mappings.
map schema_type_mapping = 1;
}
// Message for validate code request arguments.
-message ValidateCode_Args {
+message ValidateCodeArgs {
// Path to the data file.
string datafile = 1;
// Data content.
@@ -1326,7 +1326,7 @@ message ValidateCode_Args {
}
// Message for validate code response.
-message ValidateCode_Result {
+message ValidateCodeResult {
// Flag indicating if validation was successful.
bool success = 1;
// Error message from validation.
@@ -1344,7 +1344,7 @@ message Position {
}
// Message for list dependency files request arguments.
-message ListDepFiles_Args {
+message ListDepFilesArgs {
// Working directory.
string work_dir = 1;
// Flag to use absolute paths.
@@ -1356,7 +1356,7 @@ message ListDepFiles_Args {
}
// Message for list dependency files response.
-message ListDepFiles_Result {
+message ListDepFilesResult {
// Root package path.
string pkgroot = 1;
// Package path.
@@ -1371,7 +1371,7 @@ message ListDepFiles_Result {
// ---------------------------------------------------------------------------------
// Message for load settings files request arguments.
-message LoadSettingsFiles_Args {
+message LoadSettingsFilesArgs {
// Working directory.
string work_dir = 1;
// Setting files to load.
@@ -1379,7 +1379,7 @@ message LoadSettingsFiles_Args {
}
// Message for load settings files response.
-message LoadSettingsFiles_Result {
+message LoadSettingsFilesResult {
// KCL CLI configuration.
CliConfig kcl_cli_configs = 1;
// List of KCL options as key-value pairs.
@@ -1429,7 +1429,7 @@ message KeyValuePair {
// ---------------------------------------------------------------------------------
// Message for rename request arguments.
-message Rename_Args {
+message RenameArgs {
// File path to the package root.
string package_root = 1;
// Path to the target symbol to be renamed.
@@ -1441,7 +1441,7 @@ message Rename_Args {
}
// Message for rename response.
-message Rename_Result {
+message RenameResult {
// List of file paths that got changed.
repeated string changed_files = 1;
}
@@ -1453,7 +1453,7 @@ message Rename_Result {
// ---------------------------------------------------------------------------------
// Message for rename code request arguments.
-message RenameCode_Args {
+message RenameCodeArgs {
// File path to the package root.
string package_root = 1;
// Path to the target symbol to be renamed.
@@ -1465,7 +1465,7 @@ message RenameCode_Args {
}
// Message for rename code response.
-message RenameCode_Result {
+message RenameCodeResult {
// Map of changed code with filename as key and modified code as value.
map changed_codes = 1;
}
@@ -1476,9 +1476,9 @@ message RenameCode_Result {
// ---------------------------------------------------------------------------------
// Message for test request arguments.
-message Test_Args {
+message TestArgs {
// Execution program arguments.
- ExecProgram_Args exec_args = 1;
+ ExecProgramArgs exec_args = 1;
// List of KCL package paths to be tested.
repeated string pkg_list = 2;
// Regular expression for filtering tests to run.
@@ -1488,7 +1488,7 @@ message Test_Args {
}
// Message for test response.
-message Test_Result {
+message TestResult {
// List of test case information.
repeated TestCaseInfo info = 2;
}
@@ -1511,7 +1511,7 @@ message TestCaseInfo {
// ---------------------------------------------------------------------------------
// Message for update dependencies request arguments.
-message UpdateDependencies_Args {
+message UpdateDependenciesArgs {
// Path to the manifest file.
string manifest_path = 1;
// Flag to vendor dependencies locally.
@@ -1519,7 +1519,7 @@ message UpdateDependencies_Args {
}
// Message for update dependencies response.
-message UpdateDependencies_Result {
+message UpdateDependenciesResult {
// List of external packages updated.
repeated ExternalPkg external_pkgs = 3;
}
diff --git a/docs/reference/xlang-api/swift-api.md b/docs/reference/xlang-api/swift-api.md
index 71f017662..3720809e3 100644
--- a/docs/reference/xlang-api/swift-api.md
+++ b/docs/reference/xlang-api/swift-api.md
@@ -12,7 +12,7 @@ The official [Swift KCL package](https://github.com/kcl-lang/lib/tree/main/swift
import KclLib
let api = API()
-var execArgs = ExecProgram_Args()
+var execArgs = ExecProgramArgs()
execArgs.kFilenameList.append("schema.k")
let result = try api.execProgram(execArgs)
```
diff --git a/docs/tools/Ide/helix.md b/docs/tools/Ide/helix.md
index 29ccae273..bcffea284 100644
--- a/docs/tools/Ide/helix.md
+++ b/docs/tools/Ide/helix.md
@@ -22,6 +22,7 @@ sidebar_position: 4
```
- **Step 2.** Amend your Helix `languages.toml` file:
+
```toml
[[language]]
name = "kcl"
@@ -33,6 +34,7 @@ sidebar_position: 4
[language-server.kcl-lsp]
command = "kcl-language-server"
```
+
- **Step 3.** Reopen Helix, create a KCL file, and begin your KCL journey!
## Features
@@ -40,6 +42,7 @@ sidebar_position: 4
This extension provides comprehensive coding assistance based on the Language Server Protocol.
+
- **Code Completion:** Completion for keywords, variable names, attributes, and more
- **Structure:** View the main definition (schema definition) and variables in KCL files
diff --git a/docs/user_docs/guides/working-with-konfig/3-quick-start.md b/docs/user_docs/guides/working-with-konfig/3-quick-start.md
index d21bee923..e3093ebdc 100644
--- a/docs/user_docs/guides/working-with-konfig/3-quick-start.md
+++ b/docs/user_docs/guides/working-with-konfig/3-quick-start.md
@@ -69,24 +69,24 @@ spec:
app.k8s.io/component: sampleapp-dev
spec:
containers:
- - env:
- - name: MY_ENV
- value: MY_VALUE
- image: nginx:1.7.8
- name: main
- ports:
- - containerPort: 80
- protocol: TCP
- resources:
- limits:
- cpu: '100m'
- memory: '100Mi'
- ephemeral-storage: '1Gi'
- requests:
- cpu: '100m'
- memory: '100Mi'
- ephemeral-storage: '1Gi'
- volumeMounts: []
+ - env:
+ - name: MY_ENV
+ value: MY_VALUE
+ image: nginx:1.7.8
+ name: main
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ resources:
+ limits:
+ cpu: "100m"
+ memory: "100Mi"
+ ephemeral-storage: "1Gi"
+ requests:
+ cpu: "100m"
+ memory: "100Mi"
+ ephemeral-storage: "1Gi"
+ volumeMounts: []
---
apiVersion: v1
kind: Namespace
@@ -100,9 +100,9 @@ metadata:
namespace: sampleappns-dev
spec:
ports:
- - nodePort: 30201
- port: 80
- targetPort: 80
+ - nodePort: 30201
+ port: 80
+ targetPort: 80
selector:
app.kubernetes.io/name: sampleapp
app.kubernetes.io/env: dev
@@ -157,24 +157,24 @@ spec:
app.k8s.io/component: sampleapp-dev
spec:
containers:
- - env:
- - name: MY_ENV
- value: MY_VALUE
- image: nginx:1.7.8
- name: main
- ports:
- - containerPort: 80
- protocol: TCP
- resources:
- limits:
- cpu: '100m'
- memory: '100Mi'
- ephemeral-storage: '1Gi'
- requests:
- cpu: '100m'
- memory: '100Mi'
- ephemeral-storage: '1Gi'
- volumeMounts: []
+ - env:
+ - name: MY_ENV
+ value: MY_VALUE
+ image: nginx:1.7.8
+ name: main
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ resources:
+ limits:
+ cpu: "100m"
+ memory: "100Mi"
+ ephemeral-storage: "1Gi"
+ requests:
+ cpu: "100m"
+ memory: "100Mi"
+ ephemeral-storage: "1Gi"
+ volumeMounts: []
---
apiVersion: v1
kind: Namespace
@@ -188,9 +188,9 @@ metadata:
namespace: sampleappns-dev
spec:
ports:
- - nodePort: 30201
- port: 80
- targetPort: 80
+ - nodePort: 30201
+ port: 80
+ targetPort: 80
selector:
app.kubernetes.io/name: sampleapp
app.kubernetes.io/env: dev
diff --git a/docs/user_docs/guides/working-with-konfig/4-best-practice.md b/docs/user_docs/guides/working-with-konfig/4-best-practice.md
index 92a0e77e5..6e6a82829 100644
--- a/docs/user_docs/guides/working-with-konfig/4-best-practice.md
+++ b/docs/user_docs/guides/working-with-konfig/4-best-practice.md
@@ -346,9 +346,9 @@ The output is
```yaml
cpuMap:
- '1': 256
- '2': 512
- '3': 1024
+ "1": 256
+ "2": 512
+ "3": 1024
cpu: 256
```
diff --git a/docs/user_docs/support/faq-kcl.md b/docs/user_docs/support/faq-kcl.md
index 8d953a419..6095390ea 100644
--- a/docs/user_docs/support/faq-kcl.md
+++ b/docs/user_docs/support/faq-kcl.md
@@ -1051,6 +1051,7 @@ import model # Error: recursively loading
## 26. When can import be omitted?
KCL files in the same folder, but not in the main package, can refer to each other without importing. For example, for the following directory structure:
+
```
.
└── root
@@ -1740,8 +1741,6 @@ configNew:
key2: value2
```
-
-
### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL
When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition
@@ -2720,12 +2719,14 @@ In summary, KCL's mixins and protocols combine concepts from various programming
We can use the `--show-hidden` or `-H` flag when use the KCL CLI to run KCL files. e.g.:
main.k
+
```python
a = 1
_b = 2
```
The output maybe as follows with the command `kcl run main.k -H`
+
```yaml
a: 1
_b: 2
diff --git a/i18n/zh-CN/docusaurus-plugin-content-blog/2024-12-24-kcl-0.11.0-release/index.md b/i18n/zh-CN/docusaurus-plugin-content-blog/2024-12-24-kcl-0.11.0-release/index.md
index 74c019e9d..31c86796f 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-blog/2024-12-24-kcl-0.11.0-release/index.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-blog/2024-12-24-kcl-0.11.0-release/index.md
@@ -20,7 +20,7 @@ KCL 团队很高兴地宣布 **KCL v0.11.0 新版本现在已经可用**!本
**感谢 KCL 在 v0.10 - v0.11 版本迭代所有社区参与者,以下排名不分先后**
-_@adamwg, @steeling, @dennybaa, @liangyuanpeng, @NishantBansal2003, @mayrf, @eminaktas, @Gmin2, @tvandinther, @diefans, @nkabir, @suin, @Chewie, @lwz23, @eminaktas,@steeling, @bozaro, @cakemanny, @Yufeireal, @andrzejgorski, @yonas, @dansrogers, @SkySingh04, @jellllly420, @slashexx, @xnull, @diefans, @zflat, @vfarcic, @spastorclovr, @patpicos, @mproffitt, @fraenkel, @irizzant, @vfarcic, @patpicos, @mproffitt, @fraenkel, @Clint, @Christopher Haar, @ron18219, @Zack Zhang, @Alexander Fuchs, @Smaine Kahlouch, @Yvan da Silva, @Jakob Maležič, @Ryan Rueth, @Christopher Haar, @kesser, @Justin B, @Evgeny Shepelyuk, @Smaine Kahlouch, @KennyZ, @Mark Altmann (Wompi), @Peter Boat, @Hai Wu, @Evgeny Shepelyuk, @anshuman singh, @Carl-Fredrik, @Larry Gadallah, @Kevin Sztern, @Nick Atzert, @Tobias Kässer, @Mike, @john thompson, @Sky Singh, @suin, @Tom van Dinther, @Stefano Borrelli, @Valer Orlovsky, @Jacob Colvin, @Sjuul Janssen, @Vyacheslav Terdunov, @Yury Tsarev_
+_@adamwg, @steeling, @dennybaa, @liangyuanpeng, @NishantBansal2003, @mayrf, @eminaktas, @Gmin2, @tvandinther, @diefans, @nkabir, @suin, @Chewie, @lwz23, @eminaktas,@steeling, @bozaro, @cakemanny, @Yufeireal, @andrzejgorski, @yonas, @dansrogers, @SkySingh04, @jellllly420, @slashexx, @xnull, @diefans, @zflat, @vfarcic, @spastorclovr, @patpicos, @mproffitt, @fraenkel, @irizzant, @vfarcic, @patpicos, @mproffitt, @fraenkel, @Clint, @Christopher Haar, @ron18219, @Zack Zhang, @Alexander Fuchs, @Smaine Kahlouch, @Yvan da Silva, @Jakob Maležič, @Ryan Rueth, @Christopher Haar, @kesser, @Justin B, @Evgeny Shepelyuk, @Smaine Kahlouch, @KennyZ, @Mark Altmann (Wompi), @Peter Boat, @Hai Wu, @Evgeny Shepelyuk, @anshuman singh, @Carl-Fredrik, @Larry Gadallah, @Kevin Sztern, @Nick Atzert, @Tobias Kässer, @Mike, @john thompson, @Sky Singh, @suin, @Tom van Dinther, @Stefano Borrelli, @Valer Orlovsky, @Jacob Colvin, @Sjuul Janssen, @Vyacheslav Terdunov, @Yury Tsarev_
## 📚 重点更新内容
@@ -30,7 +30,7 @@ _@adamwg, @steeling, @dennybaa, @liangyuanpeng, @NishantBansal2003, @mayrf, @emi
- KCL 新增对 Alpine Linux(musl) 平台的支持。
- KCL 重构了 Parser 部分的实现,重新组织了 import 依赖的 parse 流程。
-- KCL 优化了 schema attribute 中对 ** 表达式的类型解析。
+- KCL 优化了 schema attribute 中对 \*\* 表达式的类型解析。
- KCL 修复了 lambda 表达式嵌套调用时不生效的问题。
- KCL 修复了 schema mixin parse 内存泄露的问题。
- KCL 修复了在有类型声明的赋值语句中函数调用表达式中的类型提升。
@@ -39,11 +39,11 @@ _@adamwg, @steeling, @dennybaa, @liangyuanpeng, @NishantBansal2003, @mayrf, @emi
#### 工具链
- 包管理工具版本选择算法上线。在 v0.11.0 版本中, KCL 包管理工具支持对依赖图中出现的同一个三方库的不同版本号进行选择,KCL 包管理工具参考了 go mod 的 mvs 算法,
-为了尽可能保证兼容性,包管理工具目前倾向于选择依赖图中出现的最新的版本而不是已经 release 的最新版本。
-在 v0.11.0 版本中,版本选择默认关闭,通过设置环境变量 `export KPM_FEATURE_GATES="SupportMVS=true"` 控制是否开启版本选择。
+ 为了尽可能保证兼容性,包管理工具目前倾向于选择依赖图中出现的最新的版本而不是已经 release 的最新版本。
+ 在 v0.11.0 版本中,版本选择默认关闭,通过设置环境变量 `export KPM_FEATURE_GATES="SupportMVS=true"` 控制是否开启版本选择。
- 包管理工具新增了新的本地三方库缓存结构,在 v0.11.0 版本中,KCL 包管理工具实现了新的本地三方库缓存结构,新的存储缓存结构对下载 git 仓库性能平均提升 88%。
-在 v0.11.0 版本中,新的缓存结构默认关闭,通过设置环境变量 `export KPM_FEATURE_GATES="SupportNewStorage=true"` 控制是否启用新的本地三方库缓存。
+ 在 v0.11.0 版本中,新的缓存结构默认关闭,通过设置环境变量 `export KPM_FEATURE_GATES="SupportNewStorage=true"` 控制是否启用新的本地三方库缓存。
- 修复 `kcl fmt` 代码注释的格式化错误。
- 修复 `kcl fmt` 在处理行连接符和注释组合时的错误。
@@ -52,11 +52,11 @@ _@adamwg, @steeling, @dennybaa, @liangyuanpeng, @NishantBansal2003, @mayrf, @emi
- KCL IntelliJ 插件发布 0.4.0 版本,支持 LSP4IJ
- IDE 可以补全目录中未 import 的 schema,并且自动补充包的 import 语句
-
+ 
- IDE 新增了 Config 块中 key 的类型 hint。
-
+ 
- IDE schema hover 中提供了 attr 默认值信息。
-
+ 
- 修复了 IDE 在 Windows 系统中的异常。
- 修复了 IDE 在复合赋值运算语句中异常的问题。
- 区分了 `any` 关键字和类型的高亮
@@ -83,6 +83,7 @@ import crypto
sha_filesha512 = crypto.filesha512("test.txt")
sha_fileblake3 = crypto.fileblake3("test.txt")
```
+
- 修复 `manifests.yaml_stream` 中 `ignore_private=False` 参数 不生效的问题。
#### 三方库
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/reference/model/regex.md
index 380df50b9..5470831ef 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/reference/model/regex.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/reference/model/regex.md
@@ -23,6 +23,7 @@ regex_replace = regex.replace(regex_source, ",", "|")
`match(string: str, pattern: str) -> bool`
尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项
+
```python
import regex
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.10/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.10/reference/model/regex.md
index 380df50b9..5470831ef 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.10/reference/model/regex.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.10/reference/model/regex.md
@@ -23,6 +23,7 @@ regex_replace = regex.replace(regex_source, ",", "|")
`match(string: str, pattern: str) -> bool`
尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项
+
```python
import regex
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11.json
new file mode 100644
index 000000000..f27afbace
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11.json
@@ -0,0 +1,136 @@
+{
+ "sidebar.user_docs.category.Getting Started": {
+ "message": "快速开始"
+ },
+ "sidebar.user_docs.category.Introduction": {
+ "message": "简介"
+ },
+ "sidebar.user_docs.category.Guides": {
+ "message": "用户手册"
+ },
+ "sidebar.user_docs.guides.category.Automation": {
+ "message": "自动化"
+ },
+ "sidebar.user_docs.category.Configuration": {
+ "message": "配置"
+ },
+ "sidebar.user_docs.category.Data Integration": {
+ "message": "数据集成"
+ },
+ "sidebar.user_docs.category.Package Management": {
+ "message": "包管理工具"
+ },
+ "sidebar.user_docs.category.Package Management Tools": {
+ "message": "包管理工具"
+ },
+ "sidebar.user_docs.category.How to": {
+ "message": "如何使用"
+ },
+ "sidebar.user_docs.category.Schema Definition": {
+ "message": "模型定义"
+ },
+ "sidebar.user_docs.category.Validation": {
+ "message": "验证"
+ },
+ "sidebar.user_docs.category.Concepts": {
+ "message": "核心概念"
+ },
+ "sidebar.user_docs.category.FAQ": {
+ "message": "常见问答"
+ },
+ "sidebar.reference.category.Tutorial": {
+ "message": "教程"
+ },
+ "sidebar.reference.category.Code Lab": {
+ "message": "代码实验室"
+ },
+ "sidebar.reference.category.Spec": {
+ "message": "语言规范"
+ },
+ "sidebar.reference.category.Errors and Warnings": {
+ "message": "错误与警告"
+ },
+ "sidebar.reference.category.Types": {
+ "message": "类型系统"
+ },
+ "sidebar.reference.category.System Package": {
+ "message": "系统模块"
+ },
+ "sidebar.reference.category.Plugin System": {
+ "message": "插件系统"
+ },
+ "sidebar.reference.category.Multi-Language": {
+ "message": "多语言集成"
+ },
+ "sidebar.reference.category.Cheat Sheet": {
+ "message": "备忘表"
+ },
+ "sidebar.reference.category.Package Management": {
+ "message": "包管理工具"
+ },
+ "sidebar.reference.category.Command Reference": {
+ "message": "命令参考"
+ },
+ "sidebar.reference.category.Advanced-Concepts": {
+ "message": "进阶概念"
+ },
+ "sidebar.reference.category.Best-Practices": {
+ "message": "最佳实践"
+ },
+ "sidebar.tools.category.Command Line Tools": {
+ "message": "命令行工具"
+ },
+ "sidebar.tools.category.KCL Tools": {
+ "message": "语言工具"
+ },
+ "sidebar.tools.category.Package Management Tools": {
+ "message": "包管理工具"
+ },
+ "sidebar.tools.category.OpenAPI Tools": {
+ "message": "OpenAPI 工具"
+ },
+ "sidebar.community.category.Community": {
+ "message": "简介"
+ },
+ "sidebar.community.category.Types": {
+ "message": "类型系统"
+ },
+ "sidebar.community.category.Contribution Guide": {
+ "message": "贡献指南"
+ },
+ "sidebar.community.category.Release Policy": {
+ "message": "发布策略"
+ },
+ "sidebar.docs.category.GitOps": {
+ "message": "GitOps",
+ "description": "The label for category GitOps in sidebar docs"
+ },
+ "sidebar.docs.category.CI Integration": {
+ "message": "CI 集成",
+ "description": "The label for category CI Integration in sidebar docs"
+ },
+ "sidebar.user_docs.category.GitOps": {
+ "message": "GitOps",
+ "description": "The label for category GitOps in sidebar user_docs"
+ },
+ "sidebar.user_docs.category.CI Integration": {
+ "message": "CI 集成",
+ "description": "The label for category CI Integration in sidebar user_docs"
+ },
+ "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": {
+ "message": "编辑或验证 Kubernetes 资源",
+ "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs"
+ },
+ "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": {
+ "message": "编辑或验证 Kubernetes 资源",
+ "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs"
+ },
+ "sidebar.docs.category.Secret Management": {
+ "message": "敏感信息管理",
+ "description": "The label for category Secret Management in sidebar docs"
+ },
+ "sidebar.user_docs.category.Secret Management": {
+ "message": "敏感信息管理",
+ "description": "The label for category Secret Management in sidebar user_docs"
+ }
+}
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11/reference/model/regex.md
index 380df50b9..5470831ef 100644
--- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11/reference/model/regex.md
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.11/reference/model/regex.md
@@ -23,6 +23,7 @@ regex_replace = regex.replace(regex_source, ",", "|")
`match(string: str, pattern: str) -> bool`
尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项
+
```python
import regex
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12.json
new file mode 100644
index 000000000..f27afbace
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12.json
@@ -0,0 +1,136 @@
+{
+ "sidebar.user_docs.category.Getting Started": {
+ "message": "快速开始"
+ },
+ "sidebar.user_docs.category.Introduction": {
+ "message": "简介"
+ },
+ "sidebar.user_docs.category.Guides": {
+ "message": "用户手册"
+ },
+ "sidebar.user_docs.guides.category.Automation": {
+ "message": "自动化"
+ },
+ "sidebar.user_docs.category.Configuration": {
+ "message": "配置"
+ },
+ "sidebar.user_docs.category.Data Integration": {
+ "message": "数据集成"
+ },
+ "sidebar.user_docs.category.Package Management": {
+ "message": "包管理工具"
+ },
+ "sidebar.user_docs.category.Package Management Tools": {
+ "message": "包管理工具"
+ },
+ "sidebar.user_docs.category.How to": {
+ "message": "如何使用"
+ },
+ "sidebar.user_docs.category.Schema Definition": {
+ "message": "模型定义"
+ },
+ "sidebar.user_docs.category.Validation": {
+ "message": "验证"
+ },
+ "sidebar.user_docs.category.Concepts": {
+ "message": "核心概念"
+ },
+ "sidebar.user_docs.category.FAQ": {
+ "message": "常见问答"
+ },
+ "sidebar.reference.category.Tutorial": {
+ "message": "教程"
+ },
+ "sidebar.reference.category.Code Lab": {
+ "message": "代码实验室"
+ },
+ "sidebar.reference.category.Spec": {
+ "message": "语言规范"
+ },
+ "sidebar.reference.category.Errors and Warnings": {
+ "message": "错误与警告"
+ },
+ "sidebar.reference.category.Types": {
+ "message": "类型系统"
+ },
+ "sidebar.reference.category.System Package": {
+ "message": "系统模块"
+ },
+ "sidebar.reference.category.Plugin System": {
+ "message": "插件系统"
+ },
+ "sidebar.reference.category.Multi-Language": {
+ "message": "多语言集成"
+ },
+ "sidebar.reference.category.Cheat Sheet": {
+ "message": "备忘表"
+ },
+ "sidebar.reference.category.Package Management": {
+ "message": "包管理工具"
+ },
+ "sidebar.reference.category.Command Reference": {
+ "message": "命令参考"
+ },
+ "sidebar.reference.category.Advanced-Concepts": {
+ "message": "进阶概念"
+ },
+ "sidebar.reference.category.Best-Practices": {
+ "message": "最佳实践"
+ },
+ "sidebar.tools.category.Command Line Tools": {
+ "message": "命令行工具"
+ },
+ "sidebar.tools.category.KCL Tools": {
+ "message": "语言工具"
+ },
+ "sidebar.tools.category.Package Management Tools": {
+ "message": "包管理工具"
+ },
+ "sidebar.tools.category.OpenAPI Tools": {
+ "message": "OpenAPI 工具"
+ },
+ "sidebar.community.category.Community": {
+ "message": "简介"
+ },
+ "sidebar.community.category.Types": {
+ "message": "类型系统"
+ },
+ "sidebar.community.category.Contribution Guide": {
+ "message": "贡献指南"
+ },
+ "sidebar.community.category.Release Policy": {
+ "message": "发布策略"
+ },
+ "sidebar.docs.category.GitOps": {
+ "message": "GitOps",
+ "description": "The label for category GitOps in sidebar docs"
+ },
+ "sidebar.docs.category.CI Integration": {
+ "message": "CI 集成",
+ "description": "The label for category CI Integration in sidebar docs"
+ },
+ "sidebar.user_docs.category.GitOps": {
+ "message": "GitOps",
+ "description": "The label for category GitOps in sidebar user_docs"
+ },
+ "sidebar.user_docs.category.CI Integration": {
+ "message": "CI 集成",
+ "description": "The label for category CI Integration in sidebar user_docs"
+ },
+ "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": {
+ "message": "编辑或验证 Kubernetes 资源",
+ "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs"
+ },
+ "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": {
+ "message": "编辑或验证 Kubernetes 资源",
+ "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs"
+ },
+ "sidebar.docs.category.Secret Management": {
+ "message": "敏感信息管理",
+ "description": "The label for category Secret Management in sidebar docs"
+ },
+ "sidebar.user_docs.category.Secret Management": {
+ "message": "敏感信息管理",
+ "description": "The label for category Secret Management in sidebar user_docs"
+ }
+}
\ No newline at end of file
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/_category_.json
new file mode 100644
index 000000000..f763b5c8d
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "社区",
+ "position": 5
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/_category_.json
new file mode 100644
index 000000000..131bb8e32
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "贡献指南",
+ "position": 4
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-code.md
new file mode 100644
index 000000000..8e8392fea
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-code.md
@@ -0,0 +1,25 @@
+---
+sidebar_position: 2
+---
+
+# 如何贡献代码?
+
+欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。
+
+## 1. 代码和注释中的错别字
+
+如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。
+
+## 2. 如何贡献 KCL 代码
+
+- 先确保本地测试环境正常
+- 修改代码并补充测试
+- 本地测试通过后提交 PR
+
+## 3. 如何贡献 VS Code 插件代码
+
+请参考 VS Code 插件仓库的相关文档
+
+## 4. 开发流程相关代码
+
+欢迎通过 Issue 和讨论组讨论。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-docs.md
new file mode 100644
index 000000000..7b846680d
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute-docs.md
@@ -0,0 +1,61 @@
+---
+sidebar_position: 1
+---
+
+# 如何贡献文档?
+
+本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。
+
+KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下:
+
+- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现
+- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学
+- 内部文档:针对企业用户的一些内部场景定制的文档
+- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎
+- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章
+
+在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。
+
+## 1. 基本规范
+
+- 除标题外,内部小标题尽量带编号,便于阅读
+- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号
+- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接
+- 有图有真相,但是不推荐过度复杂的架构图
+- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式
+
+**标点和空格**
+
+- 在中文的文档中优先使用中文的标点
+- 中文和英文之间需要增加 1 个空格
+- 中文和数字之间需要增加 1 个空格
+- 中文使用全角标点,标点前后均不添加空格
+- 英文内容使用半角标点,标点后面加 1 个空格
+- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。
+
+**图片和资源文件名**
+
+- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成
+- 当前文档的图片放在当前目录的 images 目录下
+- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片
+
+## 2. 使用文档内容的基本模式
+
+每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容:
+
+1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图
+1. 依赖的环境:需要安装什么工具,并给出相关链接
+1. 引入本文构建资源的关系图或架构图
+ - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接
+1. 具体的操作步骤
+ - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接
+ - 列出每个步骤命令的概要输出信息,并配以文字描述
+1. 给出测试方式
+ - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试
+ - 给出测试结果的截图(和开头呼应)
+1. 总结和展望
+ - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接)
+
+## 3. 测试和提交 PR
+
+先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute.md
new file mode 100644
index 000000000..692df6ab8
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/contribute.md
@@ -0,0 +1 @@
+# 贡献指南
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/git-guideline.md
new file mode 100644
index 000000000..c475057df
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/contribute/git-guideline.md
@@ -0,0 +1,132 @@
+# Git 提交指南
+
+本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。
+
+## 1. 关于 issue
+
+在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。
+
+如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。
+
+- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。
+- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。
+- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。
+- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。
+
+在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。
+
+## 2. 关于 Git 分支
+
+要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。
+推荐的格式如下:
+
+```
+{type}-{a_short_description}
+```
+
+分支名称主要包括两个字段,并通过 “-” 分割。其中:
+
+- {type} : 当前分支内容的类型。
+- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。
+
+e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。
+
+## 3. 关于 Git Commit
+
+我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。
+
+```
+注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen
+是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物
+(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。
+
+您可以 git add {filename} 选择要提交的文件而忽视中间产物。
+或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物:
+# commitizen
+package.json
+package-lock.json
+node_modules/*
+```
+
+如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。
+
+```
+{type} ( {component_or_file} ) {a_short_description}
+ {a_longer_description}
+ BREAKING CHANGE: {breaking_change_description}.
+ {linked issue}
+```
+
+其中主要包括6个字段:
+
+- {type} : 当前 commit 对应的分支的类型。
+- {component_or_file}: 当前 commit 改动的模块或者文件的名称。
+- {a_short_description}: 简短的描述介绍 commit 中的内容。
+- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。
+- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。
+- {linked issue}: 与当前这个 commit 关联的 issue。
+
+其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。
+
+e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。
+
+```
+
+ fix(kcl-printer): fix an output format bug in kcl-printer
+
+ There is an output format bug in kcl-printer because ...,
+ So, The calling of method "XXX" is replaced by "HHHH"...,
+ ...
+
+ -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。
+
+ BREAKING CHANGE: This change maybe cause .......
+
+ fix #123
+
+```
+
+## 4. 关于 pull request
+
+在提交一个 PR 之前,可能需要优先考虑以下几个问题:
+
+- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。
+- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。
+- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。
+- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。
+- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。
+- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。
+
+我们建议PR的标题与分支名、commit message 风格保持一致:
+
+```
+{type} ( {component_name_or_file_name} ) :{a_short_description}
+```
+
+e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。
+
+```
+fix(kcl-printer): fix an output format bug in kcl-printer.
+```
+
+## 5. 目前 type 支持的类型
+
+参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下:
+
+```
+- feat: -- 添加了新的功能特性。
+- fix: -- 进行了 Bug 的修复。
+- docs: -- 进行了文档部分的修改。
+- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。
+- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。
+- perf: -- 对代码进行了性能优化。
+- test: -- 添加或者调整已有的测试用例。
+- build: -- 对构建系统或者外部依赖库进行了调整。
+- ci: -- 调整了 CI 的配置文件或者脚本。
+- chore: -- 对源代码和测试文件之外其他部分的调整。
+- revert: -- 对 commit 进行回滚。
+```
+
+## 6. Contributor License Agreement (CLA)
+
+在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/_category_.json
new file mode 100644
index 000000000..e4cb1869c
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "简介",
+ "position": 1
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/intro.md
new file mode 100644
index 000000000..af94bc332
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/intro.md
@@ -0,0 +1,9 @@
+---
+sidebar_position: 1
+---
+
+# 社区
+
+欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码,
+
+可以查看[社区](https://github.com/kcl-lang/community)并加入我们。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/license.md
new file mode 100644
index 000000000..fe1db435a
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/license.md
@@ -0,0 +1,211 @@
+---
+sidebar_position: 99
+---
+
+# 许可
+
+KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0):
+
+```
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2023 The KCL Authors. All rights reserved.
+
+ Licensed 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.
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/support.md
new file mode 100644
index 000000000..70ecd7e81
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/intro/support.md
@@ -0,0 +1,19 @@
+---
+sidebar_position: 1
+---
+
+# 寻求帮助
+
+KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。
+
+在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。
+
+## 讨论
+
+- 在 Github 上提交问题
+- 在 Github 讨论组中交流
+- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。
+
+## 新功能
+
+请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系!
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/_category_.json
new file mode 100644
index 000000000..bf01a0535
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "发布策略",
+ "position": 3
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/index.md
new file mode 100644
index 000000000..a4a0bc3d1
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/index.md
@@ -0,0 +1 @@
+# 发布策略
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/kcl.md
new file mode 100644
index 000000000..d9c919114
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/kcl.md
@@ -0,0 +1,33 @@
+# KCL 发布策略
+
+KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。
+
+KCL 项目版本发布策略如下:
+
+- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。
+- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。
+- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。
+- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。
+- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。
+- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。
+
+## 发布流程与规则
+
+- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。
+- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。
+- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。
+- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。
+- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。
+- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。
+- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。
+- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。
+
+## 一个 Feature 的生命周期
+
+- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。
+- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。
+- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。
+- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。
+- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。
+
+> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/roadmap.md
new file mode 100644
index 000000000..eff9b2e3a
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/community/release-policy/roadmap.md
@@ -0,0 +1,4 @@
+# 路线规划
+
+- 2023 路线规划: https://github.com/kcl-lang/kcl/issues/29
+- 2024 路线规划: https://github.com/kcl-lang/kcl/issues/882
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/_category_.json
new file mode 100644
index 000000000..1910abe40
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "参考手册",
+ "position": 5
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/_category_.json
new file mode 100644
index 000000000..7839b7a27
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "备忘录",
+ "position": 10
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/index.md
new file mode 100644
index 000000000..6bfb2e4c2
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/cheatsheets/index.md
@@ -0,0 +1,5 @@
+# KCL 备忘录
+
+
+
+[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf)
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/index.md
new file mode 100644
index 000000000..9fd0c2763
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/index.md
@@ -0,0 +1 @@
+# 学习 KCL
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/_category_.json
new file mode 100644
index 000000000..6066c82bc
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "KCL",
+ "position": 1
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/_category_.json
new file mode 100644
index 000000000..c01334437
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "代码实验室",
+ "position": 2
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/collaborative.md
new file mode 100644
index 000000000..883f48533
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/collaborative.md
@@ -0,0 +1,345 @@
+---
+title: "使用配置操作分块编写配置"
+linkTitle: "使用配置操作分块编写配置"
+type: "docs"
+weight: 2
+description: 使用配置操作分块编写配置
+sidebar_position: 3
+---
+
+## 1. Introduction
+
+KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。
+
+在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。
+
+### 本节将会学习
+
+1. 定义 schema 并组织项目目录。
+2. 通过KCL的配置操作功能创建多个环境配置。
+3. 配置编译参数和测试。
+
+## 2. 定义 Schema 和 组织项目目录
+
+### Schema 定义
+
+假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式:
+
+```python
+import units
+
+type Unit = units.NumberMultiplier
+
+schema Server:
+ replicas: int = 1
+ image: str
+ resource: Resource = {}
+ mainContainer: Main = {}
+ labels?: {str:str}
+ annotations?: {str:str}
+
+schema Main:
+ name: str = "main"
+ command?: [str]
+ args?: [str]
+ ports?: [Port]
+
+schema Resource:
+ cpu?: int = 1
+ memory?: Unit = 1024Mi
+ disk?: Unit = 10Gi
+
+schema Port:
+ name?: str
+ protocol: "HTTP" | "TCP"
+ port: 80 | 443
+ targetPort: int
+
+ check:
+ targetPort > 1024, "targetPort must be larger than 1024"
+```
+
+在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。
+
+### 项目目录
+
+为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录:
+
+```
+.
+├── appops
+│ └── test_app
+│ ├── base
+│ │ └── base.k
+│ ├── dev
+│ │ ├── ci-test
+│ │ │ └── stdout.golden.yaml
+│ │ ├── kcl.yaml
+│ │ └── main.k
+│ └── prod
+│ ├── ci-test
+│ │ └── stdout.golden.yaml
+│ ├── kcl.yaml
+│ └── main.k
+├── kcl.mod
+└── pkg
+ └── sever.k
+```
+
+该项目目录主要包含三个部分:
+
+- `kcl.mod`:用于标识KCL项目的根目录的文件。
+- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。
+- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。
+ - `base`:供所有环境使用的应用程序通用配置。
+ - `dev`:供开发环境使用的应用程序配置。
+ - `prod`:供生产环境使用的应用程序配置。
+
+后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。
+
+## 3. 通过 KCL 配置操作功能创建多个环境配置
+
+### 创建基线配置
+
+在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。
+
+对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置:
+
+```python
+import pkg
+
+server: pkg.Server {
+ # 设置镜像的值为 "nginx:1.14.2"
+ image = "nginx:1.14.2"
+ # 添加 app label
+ labels.app = "test_app"
+ # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}]
+ mainContainer.ports = [{
+ protocol = "HTTP"
+ port = 80
+ targetPort = 1100
+ }]
+}
+```
+
+正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。
+
+KCL 命令:
+
+```bash
+kcl appops/test_app/base/base.k
+```
+
+输出:
+
+```yaml
+server:
+ replicas: 1
+ image: nginx:1.14.2
+ resource:
+ cpu: 1
+ memory: 1073741824
+ disk: 10737418240
+ mainContainer:
+ name: main
+ ports:
+ - protocol: HTTP
+ port: 80
+ targetPort: 1100
+ labels:
+ app: test_app
+```
+
+当前,我们已经有了一个基线配置。
+
+### 创建多重环境配置
+
+接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置:
+
+```python
+import pkg
+
+server: pkg.Server {
+ # 覆盖 base 配置中的声明的镜像
+ image = "nginx:1.14.2-dev"
+}
+```
+
+KCL 命令:
+
+```bash
+kcl appops/test_app/base/base.k appops/test_app/dev/main.k
+```
+
+输出:
+
+```yaml
+server:
+ replicas: 1
+ image: nginx:1.14.2-dev
+ resource:
+ cpu: 1
+ memory: 1073741824
+ disk: 10737418240
+ mainContainer:
+ name: main
+ ports:
+ - protocol: HTTP
+ port: 80
+ targetPort: 1100
+ labels:
+ app: test_app
+```
+
+可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中:
+
+```python
+import pkg
+
+server: pkg.Server {
+ # 覆盖 base 配置中的声明的镜像
+ image = "nginx:1.14.2-dev"
+ # 将新标签 env 合并到 base 标签中
+ labels.env = "dev"
+}
+```
+
+KCL 命令:
+
+```bash
+kcl appops/test_app/base/base.k appops/test_app/dev/main.k
+```
+
+```yaml
+server:
+ replicas: 1
+ image: nginx:1.14.2-dev
+ resource:
+ cpu: 1
+ memory: 1073741824
+ disk: 10737418240
+ mainContainer:
+ name: main
+ ports:
+ - protocol: HTTP
+ port: 80
+ targetPort: 1100
+ labels:
+ app: test_app
+ env: dev
+```
+
+可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。
+
+此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码:
+
+```python
+import pkg
+
+server: pkg.Server {
+ # 覆盖 base 配置中的声明的镜像
+ image = "nginx:1.14.2-dev"
+ # 将新标签 env 合并到 base 标签中
+ labels.env = "dev"
+ # 在 base ports配置中添加一个 port
+ mainContainer.ports += [{
+ protocol = "TCP"
+ port = 443
+ targetPort = 1100
+ }]
+}
+```
+
+KCL 命令:
+
+```bash
+kcl appops/test_app/base/base.k appops/test_app/dev/main.k
+```
+
+输出:
+
+```yaml
+server:
+ replicas: 1
+ image: nginx:1.14.2-dev
+ resource:
+ cpu: 1
+ memory: 1073741824
+ disk: 10737418240
+ mainContainer:
+ name: main
+ ports:
+ - protocol: HTTP
+ port: 80
+ targetPort: 1100
+ - protocol: TCP
+ port: 443
+ targetPort: 1100
+ labels:
+ app: test_app
+ env: dev
+```
+
+使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。
+
+```python
+import pkg
+
+server: pkg.Server {
+ # 将新标签 env 合并到 base 标签中
+ labels.env = "prod"
+}
+```
+
+KCL 命令:
+
+```bash
+kcl appops/test_app/base/base.k appops/test_app/prod/main.k
+```
+
+输出:
+
+```yaml
+server:
+ replicas: 1
+ image: nginx:1.14.2
+ resource:
+ cpu: 1
+ memory: 1073741824
+ disk: 10737418240
+ mainContainer:
+ name: main
+ ports:
+ - protocol: HTTP
+ port: 80
+ targetPort: 1100
+ labels:
+ app: test_app
+ env: prod
+```
+
+## 4. 配置编译参数和测试
+
+在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中:
+
+```yaml
+kcl_cli_configs:
+ files:
+ - ../base/base.k
+ - main.k
+ output: ./ci-test/stdout.golden.yaml
+```
+
+然后我们可以使用以下命令在开发环境中编译配置:
+
+```bash
+cd appops/test_app/dev && kcl -Y ./kcl.yaml
+```
+
+此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。
+
+## 5. 最后
+
+恭喜!
+
+我们已经完成了关于 KCL 的第三课。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/index.md
new file mode 100644
index 000000000..123c0878c
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/index.md
@@ -0,0 +1 @@
+# 代码实验室
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/schema.md
new file mode 100644
index 000000000..4e82619c5
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/schema.md
@@ -0,0 +1,817 @@
+---
+title: "使用 KCL Schema 编写复杂配置"
+linkTitle: "使用 KCL Schema 编写复杂配置"
+type: "docs"
+weight: 2
+description: 使用 KCL Schema 编写复杂配置
+sidebar_position: 2
+---
+
+## 1. 介绍
+
+KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。
+
+在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。
+
+### 本节将会学习
+
+1. 定义一个简单的 schema
+2. 为 schema 字段设置默认的不可变值
+3. 基于简单的 schema 创建配置
+4. 在 schema 中编写复杂的逻辑
+5. 通过 schema 的组合创建新的 schema
+6. 使用 dict/map 创建具有深度嵌套 schema 的配置
+7. 通过 schema 继承创建新的 schema
+8. 通过多个 mixin schema 创建新的 schema
+9. 声明 schema 验证规则
+10. 配置 schema 的输出布局
+11. 共享和重用 schema
+
+## 2. 编写简单的 Schema
+
+假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema:
+
+```python
+schema Deployment:
+ name: str
+ cpu: int
+ memory: int
+ image: str
+ service: str
+ replica: int
+ command: [str]
+ labels: {str:str}
+```
+
+在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。
+
+另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。
+
+```python
+schema Deployment:
+ name: str
+ cpu: int
+ memory: int
+ image: str
+ service: str
+ replica: int
+ command: [str]
+ labels?: {str:str} # labels 是一个可选的参数
+```
+
+当存在继承关系时:
+
+- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。
+- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。
+
+## 3. Enhance Schema as Needed
+
+Suppose we need to set default values to service and replica, we can make them as below:
+
+```python
+schema Deployment:
+ name: str
+ cpu: int
+ memory: int
+ image: str
+ service: str = "my-service" # defaulting
+ replica: int = 1 # defaulting
+ command: [str]
+ labels?: {str:str} # labels is an optional attribute
+```
+
+And then we can set the service type annotation as the string literal type to make it immutable:
+
+```python
+schema Deployment:
+ name: str
+ cpu: int
+ memory: int
+ image: str
+ service: "my-service" = "my-service"
+ replica: int = 1
+ command: [str]
+ labels?: {str:str}
+```
+
+In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`.
+
+Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`.
+
+## 4. 基于简单 Schema 创建配置
+
+现在我们有了一个简单的 schema 定义,我们可以用它来定义配置:
+
+```python
+nginx = Deployment {
+ name = "my-nginx"
+ cpu = 256
+ memory = 512
+ image = "nginx:1.14.2"
+ command = ["nginx"]
+ labels = {
+ run = "my-nginx"
+ env = "pre-prod"
+ }
+}
+```
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+ kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+nginx:
+ name: my-nginx
+ cpu: 256
+ memory: 512
+ image: nginx:1.14.2
+ service: my-service
+ replica: 1
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+```
+
+> 有关集合数据类型和块的更多详细信息,请查看手册和规范。
+
+此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。
+
+```python
+nginx = Deployment {
+ name = "my-nginx"
+ cpu = 256
+ memory = 512
+ image = "nginx:1.14.2"
+ command = ["nginx"] # 忽略行尾的逗号
+ labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式
+ labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式
+}
+```
+
+## 5. 在 Schema 中编写更为复杂的逻辑
+
+假设我们有一些schema逻辑,我们可以将它包装进 schema 中:
+
+```python
+schema Deployment[priority]:
+ name: str
+ image: str
+ service: "my-service" = "my-service"
+ replica: int = 1
+ command: [str]
+ labels?: {str:str}
+
+ _cpu = 2048
+ if priority == 1:
+ _cpu = 256
+ elif priority == 2:
+ _cpu = 512
+ elif priority == 3:
+ _cpu = 1024
+ else:
+ _cpu = 2048
+
+ cpu: int = _cpu
+ memory: int = _cpu * 2
+```
+
+现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式:
+
+```python
+nginx = Deployment(priority=2) {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ command = ["nginx"]
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+}
+```
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+nginx:
+ name: my-nginx
+ cpu: 512
+ memory: 1024
+ image: nginx:1.14.2
+ service: my-service
+ replica: 1
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+```
+
+## 6. 通过 Schema 组合创建新 Schema
+
+现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作:
+
+```python
+schema Deployment[priority]:
+ name: str
+ volumes?: [Volume]
+ image: str
+ service?: Service
+ replica: int = 1
+ command: [str]
+ labels?: {str:str}
+
+ if priority == 1:
+ _cpu = 256
+ elif priority == 2:
+ _cpu = 512
+ elif priority == 3:
+ _cpu = 1024
+ else:
+ _cpu = 2048
+
+ cpu: int = _cpu
+ memory: int = _cpu * 2
+
+schema Port:
+ name: str
+ protocol: str
+ port: int
+ targetPort: int
+
+schema Service:
+ name: "my-service" = "my-service"
+ ports: [Port]
+
+schema Volume:
+ name: str
+ mountPath: str
+ hostPath: str
+```
+
+在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。
+
+## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置
+
+现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。
+
+使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx:
+
+```python
+nginx = Deployment(priority=2) {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ volumes = [Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+ service.ports = [Port {
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+}
+```
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+nginx:
+ name: my-nginx
+ cpu: 512
+ memory: 1024
+ volumes:
+ - name: mydir
+ mountPath: /test-pd
+ hostPath: /data
+ image: nginx:1.14.2
+ service:
+ name: my-service
+ ports:
+ - name: http
+ protocol: TCP
+ port: 80
+ targetPort: 9376
+ replica: 1
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+```
+
+请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下:
+
+```python
+nginx = Deployment(priority=2) {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ volumes = [Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+ service.ports = [Port {
+ name = "http"
+ protocol = "TCP"
+ port = [80] # 错误的数据类型,试图将 List 分配给 int
+ targetPort = 9376
+ }]
+}
+```
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+kcl my_config.k
+```
+
+标准错误输出:
+
+```
+The type got is inconsistent with the type expected: expect int, got [int(80)]
+```
+
+## 8. 声明 Schema 验证规则
+
+现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。
+
+但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例:
+
+```python
+import regex
+
+schema Deployment[priority]:
+ name: str
+ volumes?: [Volume]
+ image: str
+ service?: Service
+ replica: int = 1
+ command: [str]
+ labels?: {str:str}
+
+ if priority == 1:
+ _cpu = 256
+ elif priority == 2:
+ _cpu = 512
+ elif priority == 3:
+ _cpu = 1024
+ else:
+ _cpu = 2048
+
+ cpu: int = _cpu
+ memory: int = _cpu * 2
+
+ check:
+ multiplyof(cpu, 256), "cpu must be a multiplier of 256"
+ regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'"
+ 1 <= replica < 100, "replica should be in range (1, 100)"
+ len(labels) >= 2 if labels, "the length of labels should be large or equal to 2"
+ "env" in labels, "'env' must be in labels"
+ len(command) > 0, "the command list should be non-empty"
+
+schema Port:
+ name: str
+ protocol: str
+ port: int
+ targetPort: int
+
+ check:
+ port in [80, 443], "we can only expose 80 and 443 port"
+ protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP"
+ 1024 < targetPort, "targetPort must be larger than 1024"
+
+schema Service:
+ name: "my-service" = "my-service"
+ ports: [Port]
+
+ check:
+ len(ports) > 0, "ports list must be non-empty"
+
+schema Volume:
+ name: str
+ mountPath: str
+ hostPath: str
+```
+
+由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。
+
+```python
+schema Volume:
+ name: str
+ mountPath: str
+ hostPath: str
+```
+
+现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置:
+
+```python
+nginx = Deployment(priority=2) {
+ name = "my-nginx"
+ image = "nginx:1142" # 镜像值不匹配正则表达式
+ volumes = [Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+ service.ports = [Port {
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+}
+```
+
+每个字段都是类型有效的,但镜像名无效。
+
+运行 KCL,我们将看到如下错误信息:
+
+KCL 命令:
+
+```python
+kcl my_config.k
+```
+
+标准错误输出:
+
+```
+Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'"
+```
+
+> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。
+
+## 9. 通过 Schema 继承创建新 Schema
+
+现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。
+
+通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。
+
+例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。
+
+```python
+schema Nginx(Deployment):
+ """ A base nginx schema """
+ name: "my-nginx" = "my-nginx"
+ image: str = "nginx:1.14.2"
+ replica: int = 3
+ command: [str] = ["nginx"]
+
+schema NginxProd(Nginx):
+ """ A prod nginx schema with stable configurations """
+ volumes: [Volume] = [{
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ """ A volume mapped to host path """
+ service: Service = {
+ ports = [{
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+ }
+ """ An 80 port to target backend server """
+```
+
+现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面:
+
+```python
+nginx = Nginx {
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+}
+```
+
+```python
+nginx = NginxProd {
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+}
+```
+
+现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。
+
+实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+kcl prod_config.k
+```
+
+标准输出:
+
+```yaml
+nginx:
+ name: my-nginx
+ cpu: 512
+ memory: 1024
+ volumes:
+ - name: mydir
+ mountPath: /test-pd
+ hostPath: /data
+ image: nginx:1.14.2
+ service:
+ name: my-service
+ ports:
+ - name: http
+ protocol: TCP
+ port: 80
+ targetPort: 9376
+ replica: 3
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+```
+
+## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance
+
+现在,我们可以通过 Deployment schema 完成服务器配置的声明。
+
+然而,通常实际情况更为复杂,部署可能有各种可选变量附件。
+
+例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装:
+
+```python
+import k8spkg.api.core.v1
+
+protocol PVCProtocol:
+ pvc?: {str:}
+
+mixin PersistentVolumeClaimMixin for PVCProtocol:
+ """
+ PersistentVolumeClaim (PVC) sample:
+ Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims
+ """
+
+ # Mix in a new attribute `kubernetesPVC`
+ kubernetesPVC?: v1.PersistentVolumeClaim
+
+ if pvc:
+ kubernetesPVC = v1.PersistentVolumeClaim {
+ metadata.name = pvc.name
+ metadata.labels = pvc.labels
+ spec = {
+ accessModes = pvc.accessModes
+ resources = pvc.resources
+ storageClassName = pvc.storageClassName
+ }
+ }
+```
+
+有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。
+
+```python
+schema Server(Deployment):
+ mixin [PersistentVolumeClaimMixin]
+ pvc?: {str:}
+ """ pvc user interface data defined by PersistentVolumeClaimMixin """
+```
+
+在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。
+
+请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。
+
+现在,如果我们想要使用 PVC 进行部署,只需声明用户界面:
+
+```python
+server = Server {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ volumes = [Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels = {
+ run = "my-nginx"
+ env = "pre-prod"
+ }
+ service.ports = [Port {
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+ pvc = {
+ name = "my_pvc"
+ accessModes = ["ReadWriteOnce"]
+ resources.requests.storage = "8Gi"
+ storageClassName = "slow"
+ }
+}
+```
+
+使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示:
+
+KCL 命令:
+
+```python
+kcl server.k
+```
+
+标准输出:
+
+```yaml
+server:
+ name: my-nginx
+ cpu: 512
+ memory: 1024
+ volumes:
+ - name: mydir
+ mountPath: /test-pd
+ hostPath: /data
+ image: nginx:1.14.2
+ service:
+ name: my-service
+ ports:
+ - name: http
+ protocol: TCP
+ port: 80
+ targetPort: 9376
+ replica: 1
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+ pvc:
+ name: my_pvc
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 8Gi
+ storageClassName: slow
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: my_pvc
+spec:
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: slow
+ resources:
+ requests:
+ storage: 8Gi
+```
+
+如果我们不需要持久卷,只需删除 pvc 配置块。
+
+## 11. 共享和重用 Schema
+
+可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。
+
+```python
+import pkg
+
+server = pkg.Server {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ volumes = [Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels.run = "my-nginx"
+ labels.env = "pre-prod"
+ service.ports = [Port {
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+}
+```
+
+另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。
+
+假设我们在 pkg 中有如下 models:
+
+```
+pkg/
+ - deploy.k
+ - server.k
+ - pvc.k
+```
+
+在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入:
+
+```python
+# 无需 import
+schema Server(Deployment):
+ mixin [PersistentVolumeClaimMixin]
+ pvc?: {str:}
+ """ pvc user interface data defined by PersistentVolumeClaimMixin """
+```
+
+然后用户必须导入 pkg 才能作为一个整体使用它:
+
+```python
+import pkg
+
+server = pkg.Server {
+ name = "my-nginx"
+ image = "nginx:1.14.2"
+ volumes = [pkg.Volume {
+ name = "mydir"
+ mountPath = "/test-pd"
+ hostPath = "/data"
+ }]
+ command = ["nginx"]
+ labels = {
+ run = "my-nginx"
+ env = "pre-prod"
+ }
+ service.ports = [pkg.Port {
+ name = "http"
+ protocol = "TCP"
+ port = 80
+ targetPort = 9376
+ }]
+}
+```
+
+运行 KCL 命令:
+
+```python
+kcl pkg_server.k
+```
+
+Output:
+
+```yaml
+server:
+ name: my-nginx
+ cpu: 512
+ memory: 1024
+ volumes:
+ - name: mydir
+ mountPath: /test-pd
+ hostPath: /data
+ image: nginx:1.14.2
+ service:
+ name: my-service
+ ports:
+ - name: http
+ protocol: TCP
+ port: 80
+ targetPort: 9376
+ replica: 1
+ command:
+ - nginx
+ labels:
+ run: my-nginx
+ env: pre-prod
+```
+
+## 12. 最后
+
+恭喜!
+
+我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/simple.md
new file mode 100644
index 000000000..32ad2612b
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/codelab/simple.md
@@ -0,0 +1,495 @@
+---
+title: "使用 KCL 编写简单配置"
+linkTitle: "使用 KCL 编写简单配置"
+type: "docs"
+weight: 2
+description: 使用 KCL 编写简单配置
+sidebar_position: 1
+---
+
+## 1. 介绍
+
+KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。
+
+在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。
+
+学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。
+
+### 本节将会学习
+
+1. 用一种可编程的方式编写简单的 key-value 配置
+2. 使用 KCL 编写简单的逻辑
+3. 使用 KCL 编写集合(collections)
+4. 使用 KCL 代码进行测试和调试
+5. 在 KCL 代码中使用内置(built-in)支持
+6. 共享和重用 KCL 代码
+7. 使用动态输入参数编写配置
+
+## 2. 编写Key-Value键值对
+
+通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。
+
+```python
+cpu = 256
+memory = 512
+image = "nginx:1.14.2"
+service = "my-service"
+```
+
+在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+KCL 命令:
+
+```bash
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+cpu: 256
+memory: 512
+image: nginx:1.14.2
+service: my-service
+```
+
+可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。
+
+## 3. 编写简单逻辑
+
+有时候我们想在配置中编写一些逻辑,那么我们就可以使用:
+
+- 以 `_` 开头的非导出可变变量(mutable and non-exported variable)
+- if-else 语句
+
+非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。
+
+这是一个示例,显示如何根据条件调整资源。
+
+KCL 命令:
+
+```python
+kcl my_config.k
+```
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+cpu = _cpu
+memory = _cpu * 2
+image = "nginx:1.14.2"
+service = "my-service"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+```python
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+cpu: 256
+memory: 512
+image: nginx:1.14.2
+service: my-service
+```
+
+.. 注意::
+KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。
+
+## 4. 编写集合
+
+我们可以使用集合来表示复杂的数据类型。已支持的集合类型有:
+
+- list
+- dict
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+cpu = _cpu
+memory = _cpu * 2
+command = ["nginx"] # 列表
+labels = {run = "my-nginx"} # a dict
+image = "nginx:1.14.2"
+service = "my-service"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+KCL 命令:
+
+```bash
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+cpu: 512
+memory: 1024
+command:
+ - nginx
+labels:
+ run: my-nginx
+image: nginx:1.14.2
+service: my-service
+```
+
+> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。
+
+## 5. 在集合中添加元素
+
+我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+_env = "pre-prod"
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+cpu = _cpu
+memory = _cpu * 2
+_command = ["nginx"] # 列表
+_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表
+command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写
+_labels = {
+ run = "my-nginx"
+ if _env:
+ env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对
+} # 字典
+labels = _labels
+image = "nginx:1.14.2"
+service = "my-service"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+```python
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+cpu: 256
+memory: 512
+command:
+ - nginx
+ - -f
+ - file
+labels:
+ run: my-nginx
+image: nginx:1.14.2
+service: my-service
+```
+
+## 6. 编写断言
+
+为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+cpu = _cpu
+memory = _cpu * 2
+command = ["nginx"] # 列表
+labels = {run = "my-nginx"} # 字典
+image = "nginx:1.14.2"
+service = "my-service"
+assert "env" in labels, "env label is a must"
+assert cpu >= 256, "cpu cannot be less than 256"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+```bash
+kcl my_config.k
+```
+
+标准错误输出:
+
+```bash
+Assertion failure: env label is a must.
+```
+
+将 env:pre-prod 对添加到标签中后,我们将得到如下输出:
+
+```yaml
+cpu: 512
+memory: 1024
+command:
+ - nginx
+labels:
+ run: my-nginx
+ env: pre-prod
+image: nginx:1.14.2
+service: my-service
+```
+
+## 7. 使用方便的内置支持
+
+更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+_name = "nginx"
+# exported variables
+cpu = _cpu
+memory = _cpu * 2
+command = [_name] # 列表
+labels = {
+ run = "my-{}".format(_name)
+ env = "pre-prod"
+} # a dict
+image = "{}:1.14.2".format(_name) # 字符串格式
+service = "my-service"
+
+# debugging
+print(labels) # 通过打印调式
+
+# test
+assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度
+assert "env" in labels, "env label is a must"
+assert cpu >= 256, "cpu cannot be less than 256"
+```
+
+此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+KCL 命令:
+
+```bash
+kcl my_config.k
+```
+
+标准输出:
+
+```yaml
+cpu: 512
+memory: 1024
+command:
+ - nginx
+labels:
+ run: my-nginx
+ env: pre-prod
+image: nginx:1.14.2
+service: my-service
+run: my-nginx
+env: pre-prod
+```
+
+注意:更多的内置函数和模块可以在 spec/module 目录中查看。
+
+## 8. 重用另一个模块的变量
+
+为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。
+
+在 `my_config.k` 中定义配置数据:
+
+```python
+_priority = 1 # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+_name = "nginx"
+
+# 可导出变量
+cpu = _cpu
+memory = _cpu * 2
+command = [_name] # 列表
+labels = {
+ run = "my-{}".format(_name)
+ env = "pre-prod"
+} # a dict
+image = "{}:1.14.2".format(_name) # 字符串格式
+service = "my-service"
+```
+
+而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`:
+
+```python
+import my_config
+
+# debugging
+print(my_config.labels) # 通过打印调试
+
+# test
+assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度
+assert "env" in my_config.labels, "env label is a must"
+assert my_config.cpu >= 256, "cpu cannot be less than256"
+```
+
+## 9. 配置输入参数
+
+有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。
+
+在这种情况下,我们可以按需传递 `priority` 和 `env` 参数:
+
+- 通过参数传递: `-D priority=1 -D env=pre-prod`
+- 可以在 KCL 代码中使用 `option` 关键字获取这些值
+
+```python
+_priority = option("priority") # 非导出可变变量
+_env = option("env") # 非导出可变变量
+_cpu = 256 # 非导出可变变量
+
+if _priority == 1:
+ _cpu = 256
+elif _priority == 2:
+ _cpu = 512
+elif _priority == 3:
+ _cpu = 1024
+else:
+ _cpu = 2048
+
+_name = "nginx"
+# 可导出变量
+cpu = _cpu
+memory = _cpu * 2
+command = [_name] # 列表
+labels = {
+ run = "my-{}".format(_name)
+ env = _env
+} # a dict
+image = "{}:1.14.2".format(_name) # 字符串格式
+service = "my-service"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+```bash
+kcl my_config.k -D priority=2 -D env=pre-prod
+```
+
+标准输出:
+
+```yaml
+cpu: 512
+memory: 1024
+command:
+ - nginx
+labels:
+ run: my-nginx
+ env: pre-prod
+image: nginx:1.14.2
+service: my-service
+```
+
+## 10. 使用 Dict 简化逻辑表达式
+
+当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。
+
+```python
+_priority = option("priority") # 非导出可变变量
+_env = option("env") # 非导出可变变量
+_priorityCpuMap = {
+ "1" = 256
+ "2" = 512
+ "3" = 1024
+}
+# 使用字典简化逻辑,默认值为2048
+_cpu = _priorityCpuMap[_priority] or 2048
+_name = "nginx"
+# 可导出变量
+cpu = _cpu
+memory = _cpu * 2
+command = [_name] # 列表
+labels = {
+ run = "my-{}".format(_name)
+ env = _env
+} # a dict
+image = "{}:1.14.2".format(_name) # 字符串格式
+service = "my-service"
+```
+
+使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据:
+
+KCL 命令:
+
+```bash
+kcl my_config.k -D priority=2 -D env=pre-prod
+```
+
+标准输出:
+
+```yaml
+cpu: 512
+memory: 1024
+command:
+ - nginx
+labels:
+ run: my-nginx
+ env: pre-prod
+image: nginx:1.14.2
+service: my-service
+```
+
+## 11. 最后
+
+恭喜!
+
+我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。
+
+建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/_category_.json
new file mode 100644
index 000000000..4f285ced9
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "错误与警告",
+ "position": 4
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/exception.md
new file mode 100644
index 000000000..265c56b7e
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/exception.md
@@ -0,0 +1,1509 @@
+---
+title: "KCL 错误与警告"
+linkTitle: "KCL 错误与警告"
+type: "docs"
+weight: 2
+description: KCL 错误与警告
+---
+
+# KCL 错误与警告
+
+文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。
+
+**注意:**
+**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。**
+
+此部分文档的主要内容包括:
+
+[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息.
+
+[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。
+
+[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息.
+
+[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。
+
+## 1.1 KCL 语法错误 (E1xxx)
+
+KCL 会出现的语法错误信息如下表所示:
+
+| ewcode | KCL exception | messages |
+| ------ | --------------------------------------------------------- | ----------------------- |
+| E1001 | [InvalidSyntaxError](#invalidsyntaxerror) | Invalid syntax |
+| E1002 | [KCLTabError](#taberror) | Tab Error |
+| E1003 | [KCLIndentationError](#indentationerror) | Indentation Error |
+| E1I37 | [IllegalArgumentSyntaxError](#illegalargumentsyntaxerror) | Illegal argument syntax |
+
+### InvalidSyntaxError
+
+如果在运行 KCL 时遇到错误:
+
+- `InvalidSyntaxError`, 对应的 encode 为 `E1001`
+
+那么此时 KCL 程序中出现了
+
+- 非法的 KCL 语法。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: InvalidSyntax
+ --> /syntax_error/general/multiple_assign/case0/main.k:1:2
+ |
+1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax
+ | ^ expected statement
+ |
+```
+
+### TabError
+
+如果在运行 KCL 时遇到错误: `TabError`
+
+那么此时 KCL 程序中出现了
+
+- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ name: str # 通过tab表示缩进
+ age: int # 通过四个空格标识缩进,
+ # 在当前运行环境中的四个空格与tab不同
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: InvalidSyntax
+ --> File /syntax_error/tab/tab_error_0/main.k:6:5
+ |
+3 | age: int = 1
+ | ^ inconsistent use of tabs and spaces in indentation
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。
+
+### IndentationError
+
+如果在运行 KCL 时遇到错误: `IndentationError`
+
+那么此时 KCL 程序中出现了
+
+- 程序缩进错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ name: str # 使用一个tab或者四个空格表示缩进
+ age: int # KCL不支持使用三个空格表示缩进
+ info: str # KCL不支持使用两个空格表示缩进
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: InvalidSyntax
+ --> /syntax_error/indent/indent_error_0/main.k:3:4
+ |
+3 | age: int # three white spaces are illegal
+ | ^ unindent 3 does not match any outer indentation level
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。
+
+### IllegalArgumentSyntaxError
+
+如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError`
+
+那么此时 KCL 程序中出现了
+
+- 参数语法错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+# KCL中带有keyword的参数必须出现在不带有keyword参数后面
+# 带有keyword的参数: type="list", default={"key": "value"}
+# 不带有keyword的参数: "key1"
+a = option(type="list", default={"key": "value"}, "key1")
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: InvalidSyntax
+ --> /option/type_convert_fail_2/main.k:3:57
+ |
+3 | a = option(type="list", default={"key": "value"}, "key1")
+ | ^ positional argument follows keyword argument
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序:
+
+```python
+func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n)
+```
+
+## 1.2 KCL 编译错误 (E2xxx)
+
+KCL 会出现的编译错误信息如下表所示:
+
+| ewcode | KCL exception | messages |
+| ------ | ----------------------------------------------------- | --------------------------------------------------- |
+| E2F04 | [CannotFindModule](#cannotfindmodule-e2f04) | Cannot find the module |
+| E2H13 | [UnKnownDecoratorError](#unknowndecoratorerror-e2h13) | UnKnown decorator |
+| E2C15 | [MixinNamingError](#mixinnamingerror-e2c15) | Illegal mixin naming |
+| E2C16 | [MixinStructureIllegal](#mixinstructureillegal-e2c16) | Illegal mixin structure |
+| E2B17 | [CannotAddMembersError](#cannotaddmemberserror-e2b17) | Cannot add members to a schema |
+| E2B20 | [IndexSignatureError](#indexsignatureerror-e2b20) | Invalid index signature |
+| E2G22 | [TypeError](#typeerror-e2g22) | The type got is inconsistent with the type expected |
+| E2L23 | [CompileError](#compileerror-e2l23) | An error occurs during compiling |
+| E2L25 | [NameError](#nameerror-e2l25) | Name Error |
+| E2L26 | [ValueError](#valueerror-e2l26) | Value Error |
+| E2L27 | [KeyError](#keyerror-e2l27) | Key Error |
+| E2L28 | [UniqueKeyError](#uniquekeyerror-e2l28) | Unique key error |
+| E2A29 | [AttributeError](#attributeerror-e2a29) | Attribute error occurs during compiling |
+| E2D32 | [MultiInheritError](#multiinheriterror-e2d32) | Multiple inheritance is illegal |
+| E2D34 | [IllegalInheritError](#illegalargumenterror-e2i36) | Illegal inheritance |
+| E2I36 | [IllegalArgumentError](#illegalargumenterror-e2i36) | Illegal argument during compiling |
+| E3L41 | [ImmutableError](#immutableerror-e3l41) | Immutable variable is modified |
+
+### CannotFindModule (E2F04)
+
+如果在运行 KCL 时遇到错误:
+
+- `CannotFindModule`, 对应的 encode 为 `E2F04`
+
+那么此时 KCL 程序中出现了
+
+- 无法找到导入模块错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+import .some0.pkg1 as some00 # some0 not found in package
+
+Name1 = some00.Name # some0.pkg1.name
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2F04]: CannotFindModule
+ --> import_abs_fail_0/app-main/main.k:1:1
+ |
+1 | import .some0.pkg1 as some00 # some0 not found in package
+ | Cannot find the module .some0.pkg1
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 在 import 路径下添加导入模块文件。
+
+### UnKnownDecoratorError (E2H13)
+
+如果在运行 KCL 时遇到错误:
+
+- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13`
+
+那么此时 KCL 程序中出现了
+
+- 未知的装饰器错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+@err_deprecated # 这是一个非法的装饰器
+schema Person:
+ firstName: str = "John"
+ lastName: str
+ name: str
+
+JohnDoe = Person {
+ name: "deprecated"
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> deprecated/unknown_fail_1/main.k:1:2
+ |
+1 | @err_deprecated # 这是一个非法的装饰器
+ | ^ UnKnown decorator err_deprecated
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查装饰器是否存在。
+
+### MixinNamingError (E2C15)
+
+如果在运行 KCL 时遇到错误:
+
+- `MixinNamingError`, 对应的 encode 为 `E2C15`
+
+那么此时 KCL 程序中出现了
+
+- Mixin 命名错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ firstName: str
+ lastName: str
+ fullName: str
+
+schema Fullname: # Mixin的名称应该以Mixin结尾
+ fullName = "{} {}".format(firstName, lastName)
+
+schema Scholar(Person):
+ mixin [Fullname]
+ school: str
+
+JohnDoe = Scholar {
+ "firstName": "John",
+ "lastName": "Doe",
+ "fullName": "Doe Jon"
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2D34]: IllegalInheritError
+ --> mixin/invalid_name_failure/main.k:10:12
+ |
+10 | mixin [Fullname]
+ | ^ illegal schema mixin object type 'Fullname'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。
+
+### MixinStructureIllegal (E2C16)
+
+如果在运行 KCL 时遇到错误:
+
+- `MixinStructureIllegal`, 对应的 encode 为 `E2C16`
+
+那么此时 KCL 程序中出现了
+
+- Mixin 结构错误。
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查作为 Mixin 的 Schema 的结构。
+
+### CannotAddMembersError (E2B17)
+
+如果在运行 KCL 时遇到错误:
+
+- `CannotAddMembersError`, 对应的 encode 为 `E2B17`
+
+那么此时 KCL 程序中出现了
+
+- 使用 Schema 中不存在的成员。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Girl:
+ gender: str = "female"
+
+alice = Girl {
+ "first": "alice", # Schema中没有成员“first”
+ "last": " Green", # Schema中没有成员“last”
+ "age": 10 # Schema中没有成员“age”
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> /invalid/add_attribute/main.k:5:5
+ |
+5 | "first": "alice",
+ | ^ Cannot add member 'first' to schema 'Girl'
+ |
+
+error[E2L23]: CompileError
+ --> /invalid/add_attribute/main.k:6:5
+ |
+6 | "last": " Green",
+ | ^ Cannot add member 'last' to schema 'Girl'
+ |
+
+error[E2L23]: CompileError
+ --> /invalid/add_attribute/main.k:7:5
+ |
+7 | "age": 10
+ | ^ Cannot add member 'age' to schema 'Girl'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 为 Schema 添加缺少的成员。
+- 不要使用 Schema 中不存在的成员。
+
+### IndexSignatureError [E2B20]
+
+如果在运行 KCL 时遇到错误:
+
+- `IndexSignatureError`, 对应的 encode 为 `E2B20`
+
+那么此时 KCL 程序中出现了
+
+1. 在一个 schema 中使用多个索引签名。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Data:
+ [str]: str
+ [str]: int # 在同一个schema中使用了多个索引签名
+
+data = Data {
+ name: "test"
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+---> index_signature/fail_1/main.k:3:5
+ |
+3 | [str]: int
+ | 5 ^ only one index signature is allowed in the schema
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 删除多余的索引签名。
+
+2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Data:
+ name: str # name
+ [name: str]: str # 已有名称为name的schema属性
+
+data = Data {
+ name: "test"
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: IndexSignatureError
+ --> index_signature/fail_2/main.k:3:5
+ |
+3 | [name: str]: str # the same name with the above attribute
+ | ^ index signature attribute name 'name' cannot have the same name as schema attributes
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。
+
+3. schema 索引签名的类型与 schema 实例化的属性类型冲突。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Data:
+ [str]: int
+
+data = Data {
+ name: "test" # 索引签名为 [str]:int, "test"的类型不是int.
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> index_signature/fail_3/main.k:5:5
+ |
+5 | name: "test" # Conflict with [str]:int, "test" is a string.
+ | ^ expected int, got str(test)
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。
+
+4. Schema 中的属性与索引签名冲突
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Data:
+ count: int # int 和 str 冲突
+ [str]: str
+
+data = Data {
+ count: 1
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: IndexSignatureError
+ --> index_signature/fail_4/main.k:2:5
+ |
+2 | count: int
+ | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 调整 Schema 属性或者调整索引签名。
+
+### TypeError (E2G22)
+
+如果在运行 KCL 时遇到错误:
+
+- `TypeError`, 对应的 encode 为 `E2G22`
+
+那么此时 KCL 程序中出现了
+
+- 静态类型检查错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ firstName: str
+ lastName: int
+
+JohnDoe = Person {
+ "firstName": "John",
+ "lastName": "Doe" # Schema中定义lastName: int
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> type/type_fail_0/main.k:7:5
+ |
+7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string.
+ | ^ expected int, got str(Doe)
+ |
+
+ --> type/type_fail_0/main.k:3:5
+ |
+3 | lastName: int
+ | ^ variable is defined here, its type is int, but got str(Doe)
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查赋给某个变量的值的类型与这个变量的类型是否一致。
+
+### CompileError (E2L23)
+
+如果在运行 KCL 时遇到错误:
+
+- `CompileError`, 对应的 encode 为 `E2L23`
+
+那么此时 KCL 程序中出现了
+
+1. 不支持的类型合并
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+_data = [1, 2, 3]
+_data |= "value"
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> union/fail/fail_1/main.k:2:1
+ |
+2 | _data |= "value"
+ | ^ unsupported operand type(s) for |: '[int]' and 'str(value)'
+ |
+```
+
+1. 不支持的操作符类型
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = None
+b = 1 + None # KCL中不支持None和int之间进行+操作
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> operator/operator_fail_0/main.k:2:5
+ |
+2 | b = 1 + None # Unsupported operand type + for int and None
+ | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 调整操作符号,使其同时支持两个操作数的类型。
+- 调整操作数,使其同时符合操作符号的约束。
+
+1. 没有定义的变量
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = 1
+b = "${c + 1}" # 'c' 没有定义
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> var_not_define_fail_0/main.k:2:8
+ |
+2 | b = "${c + 1}" # 'c' is not defined
+ | ^ name 'c' is not defined
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 对未定义的变量进行定义。
+- 在表达式中去掉对未定义变量的操作。
+
+4. 无效的赋值表达式
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+# pkg.k
+a = 1
+
+# main.k
+import pkg
+pkg.a |= 2
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> pkg_inplace_modify_1/main.k:3:1
+ |
+6 | pkg |= 2
+ | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查赋值表达式的内容。
+
+1. 无效的字符串表达式
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = 1
+b = "${b = a + 1}" # Invalid string interpolation expression
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> invalid_format_value_fail_0/main.k:2:5
+ |
+2 | b = "${b = a + 1}"
+ | 5 ^ invalid string interpolation expression 'b = a + 1'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查字符串表达式的内容。
+
+1. 无效的循环变量
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+data = {"key1": "value1", "key2": "value2"}
+dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> dict/invalid_loop_var_fail_0/main.k:2:25
+ |
+2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2
+ | ^ the number of loop variables is 3, which can only be 1 or 2
+ |
+```
+
+### NameError (E2L25)
+
+如果在运行 KCL 时遇到错误:
+
+- `NameError`, 对应的 encode 为 `E2L25`
+
+那么此时 KCL 程序中出现了
+
+- 试图访问的变量名不存在
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查报错信息中出现的变量是否存在。
+
+### ValueError (E2L26)
+
+如果在运行 KCL 时遇到错误:
+
+- `ValueError`, 对应的 encode 为 `E2L26`
+
+那么此时 KCL 程序中出现了
+
+- 值错误,传给参数的类型不正确
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查参数的具体类型。
+
+### KeyError (E2L27)
+
+如果在运行 KCL 时遇到错误:
+
+- `KeyError`, 对应的 encode 为 `E2L27`
+
+那么此时 KCL 程序中出现了
+
+- 使用了 dict 中不存在的 key 时引发的 key 错误
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查字典中是否存在 key。
+
+### UniqueKeyError (E2L28)
+
+如果在运行 KCL 时遇到错误:
+
+- `UniqueKeyError`, 对应的 encode 为 `E2L28`
+
+那么此时 KCL 程序中出现了
+
+- 变量同名或重复定义。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ name: str = "kcl"
+ age: int = 1
+
+schema Person:
+ aa: int
+
+x0 = Person{}
+x1 = Person{age:101}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L28]: UniqueKeyError
+ --> /schema/same_name/main.k:5:8
+ |
+5 | schema Person:
+ | ^ Unique key error name 'Person'
+ |
+
+ --> /schema/same_name/main.k:1:8
+ |
+1 | schema Person:
+ | ^ The variable 'Person' is declared here
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查出现错误的名称是否已经被使用。
+
+### AttributeError (E2A29)
+
+如果在运行 KCL 时遇到错误:
+
+- `AttributeError`, 对应的 encode 为 `E2A29`
+
+那么此时 KCL 程序中出现了
+
+- Schema 的属性错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+# pkg
+schema A:
+ field_A: str
+
+# main
+import pkg as p
+
+a = p.D + 1
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2G22]: TypeError
+ --> /import/module/no_module_attr_fail_0/main.k:4:5
+ |
+4 | a = p.D + 1
+ | ^ module 'pkg' has no attribute D
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 在使用 Schema 属性时检查这个属性是否存在。
+
+### MultiInheritError (E2D32)
+
+如果在运行 KCL 时遇到错误:
+
+- `MultiInheritError`, 对应的 encode 为 `E2D32`
+
+那么此时 KCL 程序中出现了
+
+- 多继承错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ firstName: str
+ lastName: str
+
+schema KnowledgeMixin:
+ firstName: int
+ subject: str
+
+schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承
+ school: str
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: InvalidSyntax
+ --> /schema/inherit/multi_inherit_fail_1/main.k:9:30
+ |
+9 | schema Scholar(KnowledgeMixin, Person):
+ | ^ expected one of [")"] got ,
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查程序的继承结构,KCL 中不支持多继承。
+
+### IllegalInheritError (E2D34)
+
+如果在运行 KCL 时遇到错误:
+
+- `IllegalInheritError`, 对应的 encode 为 `E2D34`
+
+那么此时 KCL 程序中出现了
+
+- 不合法的继承结构
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema FullnameMixin:
+ fullName = "{} {}".format(firstName, lastName)
+
+schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin
+ school: str
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+Invalid value for top level arguments
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- KCL 中 Schema 支持单继承 Schema。
+
+### IllegalArgumentError (E2I36)
+
+如果在运行 KCL 时遇到错误:
+
+- `IllegalArgumentError`, 对应的 encode 为 `E2I36`
+
+那么此时 KCL 程序中出现了
+
+- 参数错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = option("key")
+
+# kcl main.k -D key=value=
+# key=value= is an illegal expression
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+Invalid value for top level arguments
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查通过命令设置的 KCL option 参数是否为合法参数。
+
+### ImmutableError (E3L41)
+
+如果在运行 KCL 时遇到错误:
+
+- `ImmutableError`, 对应的 encode 为 `E3L41`
+
+那么此时 KCL 程序中出现了
+
+- 不可变量的值发生改变
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = 2147483646
+a += 1
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E1001]: ImmutableError
+ --> augment_assign/main.k:2:1
+ |
+2 | a += 1
+ | ^ Immutable variable 'a' is modified during compiling
+ |
+
+ --> augment_assign/main.k:1:1
+ |
+1 | a = 2147483646
+ | ^ The variable 'a' is declared here firstly
+ |
+note: change the variable name to '_a' to make it mutable
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。
+
+## 1.3 KCL 运行时错误 (E3xxx)
+
+KCL 会出现的运行时错误信息如下表所示:
+
+| ewcode | KCL exception | messages |
+| ------ | ------------------------------------------------------------------- | --------------------------------------------------- |
+| E3F06 | [RecursiveLoad](#recursiveload-e3f06) | Recursively loading module |
+| E3K04 | [FloatOverflow](#floatoverflow-e3k04) | Float overflow |
+| E3K09 | [IntOverflow](#intoverflow-e3k09) | Integer overflow |
+| E3N11 | [DeprecatedError](#deprecatederror-e3n11) | Deprecated error |
+| E3A30 | [AttributeRuntimeError](#attributeruntimeerror-e3a30) | Attribute error occurs at runtime |
+| E3G21 | [TypeRuntimeError](#typeruntimeerror-e3g21) | The type got is inconsistent with the type expected |
+| E3B17 | [SchemaCheckFailure](#schemacheckfailure-e3b17) | Schema check is failed to check condition |
+| E3B19 | [CannotAddMembersRuntimeError](#cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema |
+| E3M38 | [EvaluationError](#evaluationerror-e3m38) | Evaluation failure |
+| E3M39 | [InvalidFormatSpec](#invalidformatspec-e3m39) | Invalid format specification |
+| E3M40 | [AssertionError](#assertionerror-e3m40) | Assertion failure |
+| E3M42 | [RecursionError](#recursionerror-e3m42) | Recursively reference |
+
+### RecursiveLoad (E3F06)
+
+如果在运行 KCL 时遇到错误:
+
+- `RecursiveLoad`, 对应的 encode 为 `E3F06`
+
+那么此时 KCL 程序中出现了
+
+- 循环导入错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```
+# module.k
+import main # module.k 导入了 main.k
+
+print('module')
+
+# main.k
+import module # main.k 导入了 module.k
+
+print('main')
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> /import/recursive_import_fail/main.k:4
+ |
+2 | import module # main.k imports module.k
+ | ^ There is a circular import reference between module main and module
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查包的导入部分是否存在循环导入的问题。
+
+### FloatOverflow (E3K04)
+
+如果在运行 KCL 时遇到错误:
+
+- `FloatOverflow`, 对应的 encode 为 `E3K04`
+
+那么此时 KCL 程序中出现了
+
+- 浮点数溢出
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+uplimit = 3.402823466e+39
+epsilon = 2.220446049250313e-16
+a = uplimit * (1 + epsilon)
+
+# kcl main.k -r -d
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /range_check_float/overflow/number_0/main.k:3:1
+ |
+3 | a = uplimit * (1 + epsilon)
+ | 3.4028234660000003e+39: A 32-bit floating point number overflow
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查浮点数的值是否在 KCL 支持的数字范围内。
+
+### IntOverflow (E3K09)
+
+如果在运行 KCL 时遇到错误:
+
+- `IntOverflow`, 对应的 encode 为 `E3K09`
+
+那么此时 KCL 程序中出现了
+
+- 整数溢出
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+_a = 9223372036854775807
+_a += 1
+
+# kcl test.k -d
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /range_check_int/augment_assign_fail_1/main.k:2:1
+ |
+2 | _a += 1
+ | 9223372036854775808: A 64 bit integer overflow
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查整数的值是否在 KCL 支持的数字范围内。
+
+### DeprecatedError (E3N11)
+
+如果在运行 KCL 时遇到错误:
+
+- `DeprecatedError`, 对应的 encode 为 `E3N11`
+
+那么此时 KCL 程序中出现了
+
+- 使用废弃代码
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ firstName: str = "John"
+ lastName: str
+ @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True)
+ name: str
+
+JohnDoe = Person {
+ name: "deprecated" # name已经过时,并且strict设置为True
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /range_check_float/overflow/number_0/main.k:7:1
+ |
+7 | JohnDoe = Person {
+ | name was deprecated since version 1.16, use firstName and lastName instead
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。
+- 调整代码,不使用已经过时的代码。
+
+### AttributeRuntimeError (E3A30)
+
+如果在运行 KCL 时遇到错误:
+
+- `AttributeRuntimeError`, 对应的 encode 为 `E3A30`
+
+那么此时 KCL 程序中出现了
+
+- 属性错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+import math
+
+a = math.err_func(1) # err_func is not found in math
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /import/module/no_module_attr_fail_2/main.k:3:5
+ |
+3 | a = math.err_func(1) # err_func is not found in math
+ | ^ module 'math' has no attribute err_func
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查属性调用是否正确。
+
+### TypeRuntimeError (E3G21)
+
+如果在运行 KCL 时遇到错误:
+
+- `TypeRuntimeError`, 对应的 encode 为 `E3G21`
+
+那么此时 KCL 程序中出现了
+
+- 类型检查错误
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ name: str = "Alice"
+
+_personA = Person {}
+_personA |= {"name" = 123.0} # name: str = "Alice"
+personA = _personA
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /fail/fail_4/main.k:2:1
+ |
+2 | name: str = "Alice"
+ | expect str, got float
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。
+
+### SchemaCheckFailure (E3B17)
+
+如果在运行 KCL 时遇到错误:
+
+- `SchemaCheckFailure`, 对应的 encode 为 `E3B17`
+
+那么此时 KCL 程序中出现了
+
+- Schema 中的 check 条件冲突
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Person:
+ lastName: str
+ age: int
+ check:
+ age < 140, "age is too large"
+
+JohnDoe = Person {
+ "lastName": "Doe",
+ "age": 1000 # Schema中的check条件为: age < 140
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /check_block/check_block_fail_1/main.k:7:11
+ |
+7 | JohnDoe = Person {
+ | ^ Instance check failed
+ |
+
+ --> /check_block/check_block_fail_1/main.k:5:1
+ |
+5 | age < 140, "age is too large"
+ | Check failed on the condition
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查 Schema 的属性与 check 中的条件是否符合
+
+### CannotAddMembersRuntimeError (E3B19)
+
+如果在运行 KCL 时遇到错误:
+
+- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19`
+
+那么此时 KCL 程序中出现了
+
+- 访问 Schema 中不存在的成员
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Name:
+ name: str
+
+schema Person:
+ name: Name
+
+person = Person {
+ name.err_name: "Alice" # err_name is not found in schema Name
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> /nest_var/nest_var_fail_1/main.k:8:5
+ |
+8 | name.err_name: "Alice" # err_name is not found in schema Name
+ | ^ Cannot add member 'err_name' to schema 'Name'
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 为 Schema 添加不存在的成员。
+- 访问 Schema 中存在的成员。
+
+### EvaluationError (E3M38)
+
+如果在运行 KCL 时遇到错误:
+
+- `EvaluationError`, 对应的 encode 为 `E3M38`
+
+那么此时 KCL 程序中出现了
+
+- 当 KCL 中数值计算过程出现了错误。
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime
+_list2 = None # _list1 is a variable, and its type can only be known at runtime
+
+result2 = _list1 + _list2 # list + NoneType is illegal
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /datatype/list/add_None_fail/main.k:1
+ |
+4 | result2 = _list1 + _list2 # list + NoneType is illegal
+ | can only concatenate list (not "NoneType") to list
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查表达式中是否存在变量为 None,或者非法的计算过程。
+
+###0 InvalidFormatSpec (E3M39)
+
+如果在运行 KCL 时遇到错误:
+
+- `InvalidFormatSpec`, 对应的 encode 为 `E3M39`
+
+那么此时 KCL 程序中出现了
+
+- 非法的字符串格式
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+a = 1
+b = 1
+data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3
+ |
+3 | data = "${a: #js}" + " $$ " # #js is illegal string
+ | ^ #js is a invalid format spec
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 将非法 String 调整为 KCL 标准支持的 String。
+
+### AssertionError (E3M40)
+
+如果在运行 KCL 时遇到错误:
+
+- `AssertionError`, 对应的 encode 为 `E3M40`
+
+那么此时 KCL 程序中出现了
+
+- Assert False
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+assert False
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E3M38]: EvaluationError
+ --> /assert/invalid/fail_0/main.k:1
+ |
+1 | assert False
+ |
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。
+
+### CycleInheritError (E2D33)
+
+如果在运行 KCL 时遇到错误:
+
+- `CycleInheritError`, 对应的 encode 为 `E2D33`
+
+那么此时 KCL 程序中出现了
+
+- 循环继承
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Parent(Son):
+ parent_field: str
+
+schema Son(GrandSon):
+ son_field: str
+
+schema GrandSon(Parent):
+ grandson_field: str
+
+parent = Parent {
+ parent_field: ""
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+error[E2L23]: CompileError
+ --> /inherit/cycle_inherit_fail_1/main.k:7:8
+ |
+7 | schema GrandSon(Parent):
+ | ^ There is a circular reference between schema GrandSon and Parent
+ |
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。
+
+### RecursionError (E3M42)
+
+如果在运行 KCL 时遇到错误:
+
+- `RecursionError`, 对应的 encode 为 `E3M42`
+
+那么此时 KCL 程序中出现了
+
+- 循环引用
+
+可能出现错误的 KCL 程序片段如下:
+
+```python
+schema Parent(Son):
+ parent_field: str
+ son: Son = Son { # Parent has attribute Son
+ parent: Parent {
+ parent_field: "123"
+ }
+ }
+
+schema Son:
+ son_field: str
+ parent: Parent = Parent { # Son has attribute Parent
+ son: Son {
+ son_field: "123"
+ }
+ }
+
+parent = Parent {
+ parent_field: "",
+}
+```
+
+KCL 在运行上述 KCL 程序片段时的输出信息如下.
+
+```shell
+thread 'main' has overflowed its stack
+fatal runtime error: stack overflow
+```
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查 Schema 中的属性成员,避免出现循环引用的问题。
+
+## 1.4 KCL 编译警告 (W2xxx)
+
+KCL 中的编译警告如下表所示:
+
+| ewcode | KCL exception | messages |
+| ------ | --------------------------------------------- | ------------------ |
+| W2K04 | [FloatUnderflow](#floatunderflow-w2k04) | Float underflow |
+| W2P10 | [InvalidDocstring](#invaliddocstring-w2p10) | Invalid docstring |
+| W2N12 | [DeprecatedWarning](#deprecatedwarning-w2n12) | Deprecated warning |
+
+### FloatUnderflow (W2K08)
+
+如果在运行 KCL 时遇到错误:
+
+- `FloatUnderflow`, 对应的 encode 为 `W2K08`
+
+可以尝试以下步骤来修复这个错误:
+
+- 检查浮点数的值是否在 KCL 支持的数字范围内。
+
+### InvalidDocstring (W2P10)
+
+如果在运行 KCL 时遇到错误:
+
+- `InvalidDocstring`, 对应的 encode 为 `W2P10`
+
+那么此时 KCL 程序中出现了
+
+- 无效的 doc 内容
+
+可以尝试以下步骤来修复这个错误:
+
+- 请按照 KCL 标准编写 doc。
+
+### DeprecatedWarning (W2N12)
+
+如果在运行 KCL 时遇到错误:
+
+- `DeprecatedWarning`, 对应的 encode 为 `W2N12`
+
+那么此时 KCL 程序中出现了
+
+- 过时的代码警告
+
+可以尝试以下步骤来修复这个错误:
+
+- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/index.md
new file mode 100644
index 000000000..e4f702ecc
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/error/index.md
@@ -0,0 +1 @@
+# 错误与警告
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/index.md
new file mode 100644
index 000000000..66fd3dde3
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/index.md
@@ -0,0 +1 @@
+# KCL
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/_category_.json
new file mode 100644
index 000000000..c088e386f
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "规范",
+ "position": 3
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/codestyle.md
new file mode 100644
index 000000000..1a2f9c985
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/codestyle.md
@@ -0,0 +1,624 @@
+---
+title: "Code Style"
+linkTitle: "Code Style"
+type: "docs"
+weight: 2
+description: Code Style
+---
+
+## Introduction
+
+This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding.
+
+## Source File Encoding
+
+KCL file encoding should always use **UTF-8**.
+
+## Code Layout
+
+### Indentation
+
+Use **4 spaces** per indentation level such as in the schema statement and if statement.
+
+```python
+schema PersonA:
+ name: str # non-recommended
+ age: int
+
+schema PersonB:
+ name: str # recommended
+ age: int
+
+if True:
+ a = 1 # recommended
+elif True:
+ b = 2 # non-recommended
+else:
+ c = 3 # non-recommended
+```
+
+The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in:
+
+```python
+# valid and recommended
+my_list = [
+ 1, 2, 3,
+ 4, 5, 6,
+]
+```
+
+```python
+# invalid
+my_list = [
+ 1, 2, 3,
+ 4, 5, 6,
+ ]
+```
+
+### Tabs or Spaces
+
+- Spaces are the preferred indentation method.
+- Tabs should be used solely to remain consistent with code that is already indented with tabs.
+
+KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time.
+
+### Blank Lines
+
+- Surround top-level schema definitions with one blank line.
+- Keep at most one blank line between two statements and remove redundant blank lines.
+- Remove extra blank characters at the end of the line
+- Remove extra blank characters in a blank line.
+- There is no blank line in the header of the file, start writing from the first line.
+- Only one blank line will be left at the end of the KCL file.
+
+```python
+# Remove blank lines in the file header
+a = 1 # Remove white space at the end of the line
+# Keep at most one blank line between two statements
+
+b = 2
+# Only leave one blank line at the end of the file
+
+```
+
+### Inline Expressions
+
+Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines.
+
+```python
+if True: print("") # non-recommended
+
+if True: # recommended
+ print("")
+```
+
+### Line Break and Continuation lines
+
+- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned.
+- The 4-space rule is optional for continuation lines.
+
+```python
+anotherString = "Too long expression " + \
+ "Too long expression " # non-recommended
+
+longString = "Too long expression " + \
+ "Too long expression " + \
+ "Too long expression " # recommended
+```
+
+### When to Use Trailing Commas
+
+- Always use trailing commas.
+
+### Maximum Line Length
+
+- The general recommendation is **80 characters** but not absolute.
+
+### Symbol Break White Space
+
+Try to keep the spaces between different symbols, but not too many, usually one is good.
+
+```python
+a = 1 # recommended
+b = 1 + 2 # non-recommended
+```
+
+### Whitespace in Expressions and Statements
+
+Avoid extraneous whitespace in the following situations:
+
+- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside.
+
+```python
+a = (1 + 2) # recommended
+b = ( 1 + 2 ) # non-recommended
+
+c = [1, 2, 3] # recommended
+d = [ 1, 2, 3 ] # non-recommended
+
+e = {key = "value"} # recommended
+f = { key = "value" } # non-recommended
+```
+
+```python
+spam(ham[1], {eggs = 2}) # recommended
+spam( ham[ 1 ], { eggs = 2 } ) # non-recommended
+```
+
+- Between a trailing comma and a following close parenthesis.
+
+```python
+foo = [0,] # recommended
+bar = [0, ] # non-recommended
+```
+
+- Immediately before the open parenthesis that starts the argument list of a function call.
+
+```python
+print(1) # recommended
+print (1) # non-recommended
+```
+
+- Immediately before the open parenthesis that starts indexing or slicing.
+
+```python
+dct = {key = "value"}
+lst = [1, 2, 3]
+
+a = dct['key'] # recommended
+b = dct ['key'] # non-recommended
+
+c = lst[0] # recommended
+d = lst [1] # non-recommended
+```
+
+- More than one space around an assignment `=` (or other) operator to align it with another.
+
+```python
+# recommended:
+x = 1
+y = 2
+long_variable = 3
+```
+
+```python
+# non-recommended:
+x = 1
+y = 2
+long_variable = 3
+```
+
+- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`).
+
+```python
+# recommended:
+i = i + 1
+submitted += 1
+x = x * 2 - 1
+hypot2 = x * x + y * y
+c = (a + b) * (a - b)
+```
+
+```python
+# non-recommended:
+i = i+1
+submitted+=1
+x = x*2 - 1
+hypot2 = x*x + y*y
+c = (a+b) * (a-b)
+```
+
+- Break one blank line between different statements e.g., import, schema and expression statements.
+
+```python
+import math
+import net
+
+schema Person:
+ name: str
+
+person = Person {
+ name = "Alice"
+}
+```
+
+- Compound statements (multiple statements on the same line) are generally discouraged
+
+```python
+# recommended:
+if foo == 'blah':
+ do_blah_thing()
+do_one()
+do_two()
+do_three()
+```
+
+```python
+# non-recommended:
+if foo == 'blah': do_blah_thing()
+do_one(); do_two(); do_three()
+```
+
+## Naming Conventions
+
+### Naming Styles
+
+The following naming styles are commonly distinguished:
+
+- `b` (single lowercase letter)
+- `B` (single uppercase letter)
+- `lowercase`
+- `lower_case_with_underscores`
+- `UPPERCASE`
+- `UPPER_CASE_WITH_UNDERSCORES`
+- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.)
+- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character)
+- `Capitalized_Words_With_Underscores` (ugly and non-recommended)
+
+### Names to Avoid
+
+Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names.
+
+### Package and Module Names
+
+Package and module names should have short, all-lowercase names.
+
+### Schema Names
+
+Schema names should normally use the `CapWords` convention.
+
+### Constants
+
+Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`.
+
+## Import
+
+- Imports should usually be on separate lines.
+- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
+- Imports should be grouped in the following order and we should put a blank line between each group of imports.
+ 1. Standard library imports.
+ 2. Related third party plugin imports.
+ 3. Local application/library specific imports.
+- Use an alias when we import a package name with a relatively long path.
+- Leave only one space between the Import keyword and the package name.
+
+```python
+import net # recommended
+import math # non-recommended
+
+import ..pkg.internal_pkg as alias_pkg # recommended
+```
+
+## Comments
+
+- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!).
+- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period.
+- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence.
+
+### Block Comments
+
+Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment).
+
+Paragraphs inside a block comment are separated by a line containing a single `#`.
+
+```python
+# This is a block comment
+a = 1
+```
+
+### Inline Comments
+
+Use inline comments sparingly.
+
+An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**.
+
+```python
+a = 1 # This is an inline comment
+```
+
+### Documentation Strings
+
+Write doc strings for all public schema and schema attributes.
+
+```python
+schema Person:
+ """
+ Person schema doc string
+ """
+
+ name: str = "Alice"
+```
+
+## String
+
+- Single-quoted strings and double-quoted strings are the same in KCL.
+- Use double-quoted string with lowercase prefix
+- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention.
+- When a string contains single or double quote characters, use the other one to avoid backslashes in the string.
+
+```python
+strC = "'123'" # recommended
+strD = "\"123\"" # non-recommended
+```
+
+## Number
+
+- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself.
+
+```python
+foo = 0xAB # recommended
+bar = 0Xab # non-recommended
+```
+
+## Operators
+
+### Binary Operators
+
+- Leave only one space before and after the assignment `=`.
+- Leave only one space before and after the binary operator in the expression.
+
+```python
+a = 1 # recommended
+b=2 # non-recommended
+c= 3 # non-recommended
+d =4 # non-recommended
+
+_value = (1 + 2 * 3) # recommended
+_value = (1+2*3) # non-recommended
+```
+
+### Unary Operators
+
+- There is only no space after unary operators e.g., `~`, `+` and `-`.
+
+```python
+_value = 1 + -2 * ~3 # recommended
+_value = 1+ - 2 * ~ 3 # non-recommended
+```
+
+- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions.
+
+```python
+_list = [1, 2, 3]
+_list = [*_list, [4, 5 ,6]] # recommended
+_list = [* _list, [4, 5 ,6]] # non-recommended
+
+_dict = {**{k = "v"}, **{k = "v"}} # recommended
+_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended
+```
+
+- Use `is not` operator rather than `not ... is`.
+
+```python
+# recommended:
+if foo is not None:
+ a = 1
+```
+
+```python
+# non-recommended:
+if not foo is None:
+ a = 1
+```
+
+## Dict
+
+- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`.
+
+```python
+d1 = {labels: {k1 = "v1"}} # recommended
+d2 = {labels : {k1 = "v1"}} # non-recommended
+d3 = {labels :{k1 = "v1"}} # non-recommended
+```
+
+- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid.
+
+```python
+d1 = {key = "value"} # recommended
+d2 = {key= "value"} # non-recommended
+d3 = {key ="value"} # non-recommended
+```
+
+```python
+d1 = {key += [0, 1, 2]} # recommended
+d2 = {key+= [0, 1, 2]} # non-recommended
+d3 = {key +=[0, 1, 2]} # non-recommended
+```
+
+- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional.
+
+```python
+d = {
+ key1 = "value1"
+ key2 = "value2"
+ key3 = "value3"
+ key4 = "value4"
+}
+```
+
+## List
+
+- Keep only **one space** after the comma `,` separating elements in the list
+
+```python
+a = [1, 2, 3] # recommended
+b = [1,2,3] # non-recommended
+```
+
+- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list.
+
+```python
+a = [i for i in range(10)] # recommended
+b = [i for i in range(10)] # non-recommended
+```
+
+## Slice
+
+- Keep the same number of spaces before and after the colon `:` of the list slice.
+
+```python
+l = [1, 2, 3]
+a = l[0:2] # recommended
+b = l[0 : 2] # non-recommended
+c = l[0: 2] # non-recommended
+
+d = l[0 + 0 : 1 + 1] # recommended
+e = l[0 + 0:1 + 1] # non-recommended
+```
+
+## Schema
+
+- Leave only one space before and after the schema attribute assignment `=`.
+- Always add a doc string to a schema, which is a good programming habit.
+
+```python
+schema Person:
+ """
+ Schema doc string
+ """
+ name: str = "Alice" # recommended
+ age : int=12 # non-recommended
+
+person = Person {}
+```
+
+- Keep **no spaces** around the schema inheritance operator `()`
+
+```python
+schema Base:
+ name: str
+
+schema Person(Base): # recommended
+ age: int
+
+schema Schema ( Base ): # non-recommended
+ age: int
+```
+
+- Keep **only one space** between the brackets and the schema name of the config at schema instantiation.
+
+```python
+schema Base:
+ name: str
+
+schema Person(Base):
+ age: int
+
+personA = Person{} # non-recommended
+personB = Person {} # recommended
+```
+
+- Keep **only one space** between the **mixin** keyword and the following `[]` operator
+
+```python
+schema NameMixin:
+ name: str = "name"
+
+schema Person:
+ mixin [NameMixin] # non-recommended
+ age: int
+
+schema Parent:
+ mixin [NameMixin] # recommended
+ age: int
+```
+
+### Attribute Annotations
+
+- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`.
+
+```python
+# recommended:
+schema Person:
+ name: str # No space before the colon `:`
+ age: int = 18 # Spaces around assignment`=`
+```
+
+```python
+# non-recommended:
+schema Person:
+ codeA:int # No space after the colon `:`
+ codeB : int # Space before the colon `:`
+ name: str="Alice" # No spaces around assignment`=`
+```
+
+- There are no spaces around the colon `:` in the dict type annotation.
+
+```python
+schema Person:
+ labels: {str:str} # recommended
+ keyValues: {str : str} # non-recommended
+```
+
+### Arguments
+
+- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs).
+
+```python
+schema Person[nameVar]:
+ # Decorator kwargs
+ @deprecated(strict=False) # recommended
+ name: str = nameVar
+
+ @deprecated(strict = False) # non-recommended
+ age: int
+
+# Schema kwargs
+personA = Person(nameVar="Alice") {} # recommended
+personB = Person(nameVar = "Bob") {} # non-recommended
+
+# Function kwargs
+print("", end='') # recommended
+print("", end = '') # non-recommended
+```
+
+### Index Signature
+
+- It is recommended to place the schema index signature before the schema attribute instead of mixed placement.
+
+```python
+schema ConfigReCommended:
+ [...str]: str # recommended
+ name: str
+ image: str
+
+schema ConfigNonReCommended:
+ name: str
+ [...str]: str # non-recommended
+ image: str
+```
+
+## Keywords
+
+- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc.
+
+```python
+schema NameMixin:
+ check:
+ name not None
+
+schema Person:
+ """
+ Person schema definition
+ """
+ mixin [NameMixin]
+
+ name: str = "Alice"
+ age: int
+
+person = Person {
+ age = 18
+}
+```
+
+## Function
+
+- There are no spaces around the function/package select operator `.`
+- There are no spaces between the function name and the parentheses `()`.
+
+```python
+import math
+
+print(math.log(10)) # recommended
+print( math . log (10)) # non-recommended
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/datatypes.md
new file mode 100644
index 000000000..ef7ea71af
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/datatypes.md
@@ -0,0 +1,452 @@
+---
+title: "Data Types"
+linkTitle: "Data Types"
+type: "docs"
+weight: 2
+description: Data Types
+---
+
+## Syntax
+
+### Bool
+
+Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value.
+
+### Int
+
+Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type.
+
+Besides, integer literals may have an `SI` or `IEC` multiplier.
+
+- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`.
+- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`.
+
+```python
+a = 1 # positive integer: 1
+b = -1 # negative integer: -1
+c = 0x10 # hexadecimal literal: 16
+d = 0o10 # octal literal: 8, or the form `010`
+e = 0b10 # binary literal: 2
+f = 10Ki # integer literal with IEC multiplier: 10240
+g = 1M # integer literal with SI multiplier: 1000000
+h = int("10") # int constructor: 10
+i = int("10Ki") # int constructor with multiplier: 10240
+```
+
+Notes:
+
+- Report an error if unable to represent an integer value precisely.
+
+### Float
+
+Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type.
+
+```python
+a = 1.10
+b = 1.0
+c = -35.59
+d = 32.3+e18
+f = -90.
+g = -32.54e100
+h = 70.2-E12
+i = float("112") # float constructor
+```
+
+Notes:
+
+- Report an error if unable to represent a floating-point value due to overflow
+- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented.
+
+#### None
+
+In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON.
+
+```python
+a = None
+b = [1, 2, None]
+c = {"key1" = "value1", "key2" = None}
+```
+
+Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations.
+
+```python
+a = 1 + None # error
+b = int(None) # error
+c = not None # True
+d = None == None # True
+e = None or 1 # 1
+f = str(None) # None
+```
+
+#### Undefined
+
+`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON.
+
+```python
+a = Undefined
+b = [1, 2, Undefined]
+c = {"key1" = "value1", "key2" = Undefined}
+```
+
+Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations.
+
+```python
+a = 1 + Undefined # error
+b = int(Undefined) # error
+c = not Undefined # True
+d = Undefined == Undefined # True
+e = Undefined or 1 # 1
+f = str(Undefined) # Undefined
+```
+
+### Common Numeric Operations
+
+Int and Float support the following operations (see built-in proposal for built-in details):
+
+- `x + y`: sum of x and y.
+- `x - y`: difference of x and y.
+- `x * y`: product of x and y.
+- `x / y`: quotient of x and y.
+- `x // y`: floored quotient of x and y.
+- `x % y`: remainder of x / y.
+- `x ** y`: x to the power y.
+- `-x`: x negated.
+- `+x`: x unchanged.
+- `~x`: x bitwise negation.
+- `abs(x)`: absolute value or magnitude of x.
+- `int(x)`: x converted to integer.
+- `float(x)`: x converted to floating point.
+
+KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point.
+
+### String
+
+Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways:
+
+```python
+'allows embedded "double" quotes' # Single quotes
+"allows embedded 'single' quotes" # Double quotes
+'''Three single quotes''', """Three double quotes""" # Triple quoted
+```
+
+Triple quoted strings may span multiple lines.
+
+Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`.
+
+```python
+a = "Hello, World!"
+b = a[2:5] # "llo"
+c = a[-5:-2] # "orl"
+d = a[::-1] # "'!dlroW ,olleH'"
+```
+
+- `str(x=None) -> str`
+
+Return a string. If _x_ is not provided, raise a runtime error.
+
+```python
+x = str(3.5) # "3.5"
+```
+
+#### Members
+
+Built-in function and members of a string
+
+- `str#len() -> int`
+ Return the number of characters in the string.
+- `capitalize() -> str`
+ Return a copy of the string with its first character (if any) capitalized and the rest lowercased.
+- `count(sub: str, start: int = 0, end: int = -1) -> int`
+ Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive.
+- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool`
+ Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive.
+- `find(sub: str, start: int = 0, end: int = -1) -> int`
+ Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive.
+- `format(*args, **kwargs) -> str`
+ Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function.
+- `index(sub: str, start: int = 0, end: int = -1) -> int`
+ Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive.
+- `isalnum() -> bool`
+ Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise.
+- `isalpha() -> bool`
+ Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character.
+- `isdigit() -> bool`
+ Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character.
+- `islower() -> bool`
+ Returns True if all cased characters in the string are lowercase and there is at least one character.
+- `isspace() -> bool`
+ Returns True if all characters are white space characters and the string contains at least one character.
+- `istitle() -> bool`
+ Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase).
+- `isupper() -> bool`
+ Returns True if all cased characters in the string are uppercase and there is at least one character.
+- `join(iterable: list) -> str`
+ Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example:
+
+ ```python
+ >>> "|".join(["a", "b", "c"])
+ "a|b|c"
+ ```
+
+- `lower() -> str`
+ Returns a copy of the string with all the cased characters converted to lowercase.
+- `lstrip(chars: str) -> str`
+ Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped:
+
+ ```python
+ >>> ' spacious '.lstrip()
+ 'spacious '
+ >>> 'www.example.com'.lstrip('cmowz.')
+ 'example.com'
+ ```
+
+- `replace(old: str, new: str, count: int) -> str`
+ Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced.
+- `rfind(sub: str, start: int = 0, end: int = -1) -> int`
+ Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure.
+- `rindex(sub: str, start: int = 0, end: int = -1) -> int`
+ Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive.
+- `rsplit(sep: str, maxsplit: int = -1) -> list`
+ Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below.
+- `rstrip(chars: str) -> str`
+ Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped:
+
+ ```python
+ >>> ' spacious '.rstrip()
+ ' spacious'
+ >>> 'mississippi'.rstrip('ipz')
+ 'mississ'
+ ```
+
+- `split(sep: str, maxsplit: int) -> list`
+ Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made).
+
+ If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`.
+
+ For example:
+
+ ```python
+ >>> '1,2,3'.split(',')
+ ['1', '2', '3']
+ >>> '1,2,3'.split(',', maxsplit=1)
+ ['1', '2,3']
+ >>> '1,2,,3,'.split(',')
+ ['1', '2', '', '3', '']
+ ```
+
+ If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`.
+
+ For example:
+
+ ```python
+ >>> '1 2 3'.split()
+ ['1', '2', '3']
+ >>> '1 2 3'.split(maxsplit=1)
+ ['1', '2 3']
+ >>> ' 1 2 3 '.split()
+ ['1', '2', '3']
+ ```
+
+- `splitlines(keepends: str) -> list`
+ Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true.
+
+ This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines.
+
+ For example:
+
+ ```python
+ >>> 'ab c\n\nde fg\rkl\r\n'.splitlines()
+ ['ab c', '', 'de fg', 'kl']
+ >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
+ ['ab c\n', '\n', 'de fg\r', 'kl\r\n']
+ ```
+
+ Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line:
+
+ ```python
+ >>> "".splitlines()
+ []
+ >>> "One line\n".splitlines()
+ ['One line']
+ ```
+
+ For comparison, `split('\n')` gives:
+
+ ```python
+ >>> ''.split('\n')
+ ['']
+ >>> 'Two lines\n'.split('\n')
+ ['Two lines', '']
+ ```
+
+- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool`
+ Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position.
+- `strip(chars: str) -> str`
+ Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped:
+
+ ```python
+ >>> ' spacious '.strip()
+ 'spacious'
+ >>> 'www.example.com'.strip('cmowz.')
+ 'example'
+ ```
+
+ The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example:
+
+ ```python
+ >>> comment_string = '#....... Section 3.2.1 Issue #32 .......'
+ >>> comment_string.strip('.#! ')
+ 'Section 3.2.1 Issue #32'
+ ```
+
+- `title() -> str`
+ Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase.
+
+ For example:
+
+ ```python
+ >>> 'Hello world'.title()
+ 'Hello World'
+ ```
+
+ The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result:
+
+ ```python
+ >>> "they're bill's friends from the UK".title()
+ "They'Re Bill'S Friends From The Uk"
+ ```
+
+- `upper() -> str`
+ Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase).
+- `removeprefix(prefix: str) -> str`
+ If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string.
+ ```python
+ >>> "prefix-data".removeprefix("prefix-")
+ "data"
+ ```
+- `rermovesuffix(suffix: str) -> str`
+ If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string.
+ ```python
+ >>> "data-suffix".removesuffix("-suffix")
+ "data"
+ ```
+
+### List
+
+Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application).
+
+Lists may be constructed in several ways:
+
+- Using a pair of square brackets to denote the empty list: `[]`
+- Using square brackets, separating items with commas: `[a]`, `[a, b, c]`
+- Using a list comprehension: `[x for x in iterable]`
+- Using the type constructor: list() or list(iterable)
+
+The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`.
+
+Lists implement all of the common sequence operations.
+
+#### Members
+
+- `len()`
+ Return the number of items in the list.
+
+### Common Sequence Operations
+
+The operations in the following table are supported by List and Dict.
+
+This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s.
+
+The `in` and `not in` operations have the same priorities as the comparison operations. The +
+(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations.
+
+| Operation | Result | Notes |
+| ------------ | -------------------------------------------------- | ----- |
+| `x in s` | `True` if an item of s is equal to x, else `False` | #1 |
+| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 |
+| `s + t` | the concatenation of s and t | #5 |
+| `s[i]` | ith item of s, origin 0 | #2 |
+| `s[i:j]` | slice of s from i to j | #2 #3 |
+| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 |
+| `min(s)` | smallest item of s | |
+| `max(s)` | largest item of s | |
+
+Notes:
+
+- 1. While the in and not in operations are used only for simple containment testing in the
+ general case, some specialized sequences (str) also use them for subsequence testing:
+
+```python
+>>> "gg" in "eggs"
+True
+```
+
+- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0.
+- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty.
+- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len()
+
+ - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1.
+
+- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below:
+
+ - if concatenating str objects, you can build a list and use `str.join()` at the end
+
+- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice.
+
+### Dict
+
+Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration.
+
+Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension.
+
+- `dict(obj)`
+
+Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`:
+
+```python
+>>> a = {'two': 2, 'one': 1, 'three': 3}
+>>> b = {'one': 1, 'two': 2, 'three': 3}
+>>> c = {'three': 3, 'one': 1, 'two': 2}
+>>> a == b == c
+True
+```
+
+Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used.
+
+In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it.
+
+```python
+>>> {str(i): 2 * i for i in range(3)}
+{"0": 0, "1": 2, "2": 4}
+
+>>> a = {"one": 1, "two": 2, "three": 3}
+>>> b = {k: v for k, v in a if v >= 2}
+{two: 2, three: 3}
+```
+
+#### Operations & Members
+
+These are the operations that dictionaries the support.
+
+- `list(d)`
+ Return a list of all the keys used in the dictionary d.
+- `len()`
+ Return the number of items in the dictionary d.
+- `d[key]`
+ Return the item of d with key. Return Undefined if key is not in the map.
+- `key in d`
+ Return True if d has a key, else False.
+- `key not in d`
+ Equivalent to not key in d.
+- `d.key`
+ Return the item of d with key. Return Undefined if key is not in the map.
+
+Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError.
+
+```python
+>>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
+>>> d
+{'one': 1, 'two': 2, 'three': 3, 'four': 4}
+>>> list(d)
+['one', 'two', 'three', 'four']
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/error.md
new file mode 100644
index 000000000..65420a2fc
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/error.md
@@ -0,0 +1,53 @@
+---
+title: "Errors"
+linkTitle: "Errors"
+type: "docs"
+weight: 2
+description: Errors
+---
+
+When errors happen, developers should be able to detect the error and abort
+execution. Thus, KCL introduce the `assert` syntax.
+
+In the previous topic of `schema` syntax. Errors can also be raised when a
+schema is violated.
+
+## Syntax
+
+The syntax of the `assert` statement is the following.
+
+```bnf
+assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)?
+```
+
+In the basic form, an `assert` statement evaluates an expression. If the
+expression is evaluated to `False`, the assertion is failed, and an error
+should be reported.
+
+In the extended form, an error message can be provided. The error message is
+another expression. It is only evaluated when the expression to be evaluated
+is evaluated to `False`. The evaluation result of the error message is printed
+when reporting the error.
+
+The following is an example:
+
+```python
+a = 1
+b = 3
+condition = False
+# a != b evaluates to True, therefore no error should happen.
+assert a != b
+# a == b is False, in the reported error message, the message "SOS" should be printed.
+assert a == b, "SOS"
+# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed.
+assert a == b if condition, "error message"
+```
+
+## The Implementation
+
+When an error happens, no matter it is caused by the `assert` or the `schema` syntax,
+the virtual machine should exit with an exit code greater than `0`.
+
+The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it.
+
+In practice, KCL can dump back trace by default, and an argument can be introduced to disable it.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/expressions.md
new file mode 100644
index 000000000..b52c10f3f
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/expressions.md
@@ -0,0 +1,915 @@
+---
+title: "Expressions"
+linkTitle: "Expressions"
+type: "docs"
+weight: 2
+description: Expressions
+---
+
+## Syntax
+
+In KCL, an expression specifies the computation of a value.
+
+The syntax is the following:
+
+```bnf
+expression: test ("," test)*
+test: if_expr | primary_expr | unary_expr | binary_expr
+```
+
+KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression.
+
+### Primary Expressions
+
+Primary expressions are the operands for unary and binary expressions.
+
+Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component.
+
+Syntax:
+
+```bnf
+primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix
+```
+
+### Operands
+
+Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression.
+
+Syntax:
+
+```bnf
+operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")"
+operand_name: identifier | qualified_identifier
+```
+
+### Identifiers
+
+In KCL, an identifier is a name, may with selectors, that identifies a value.
+
+Syntax:
+
+```bnf
+identifier: NAME
+```
+
+Examples:
+
+```python
+x
+a
+_b
+```
+
+Use the `$` character prefix to define keyword identifiers.
+
+```python
+$if = 1
+$else = "s"
+```
+
+Please note: whether the non-keyword identifier is prefixed with `$` has the same effect.
+
+```python
+_a = 1
+$_a = 2 # equal to `_a = 2`
+```
+
+To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`:
+
+Syntax:
+
+```bnf
+qualified_identifier: identifier "." identifier
+```
+
+Examples:
+
+```python
+pkg.a
+```
+
+The package name in qualified_identifier must be imported.
+
+### Basic Literals
+
+Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value.
+
+Syntax:
+
+```bnf
+operand: number | string | "True" | "False" | "None" | "Undefined"
+```
+
+Examples:
+
+```python
+1
+2.3
+"abc"
+True
+False
+None
+Undefined
+```
+
+See more details about **data type** spec.
+
+### Parenthesized Expressions
+
+An expression enclosed in parentheses yields the result of that expression.
+
+Syntax:
+
+```bnf
+operand: '(' expression ')'
+```
+
+Examples:
+
+```python
+x = (1 + 2) * (3 + 4) # 21
+```
+
+### Dictionary Expressions
+
+A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair.
+
+```bnf
+config_expr: '{' config_entries '}'
+config_entries: config_entry [config_entry*]
+config_comp: '{' (config_entry comp_clause+) '}'
+config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry
+double_star_expr: "**" expression
+if_entry:
+ 'if' expr ';' if_entry_exec_block
+ ('elif' expr ':' if_entry_exec_block)*
+ ('else' ':' if_entry_exec_block)?
+NEWLINE: '/r?/n'
+```
+
+Examples:
+
+```python
+{}
+{"one": 1}
+{"one": 1, "two": 2}
+```
+
+The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times.
+
+Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists.
+
+We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines:
+
+```python
+data = {
+ "key1" = "value1" # Ignore the comma ',' at the end of line
+ "key2" = "value2"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+We can ignore the key quotation marks when we writing simple literals on the key.
+
+```python
+data = {
+ key1 = "value1" # Ignore the comma ',' at the end of line
+ key2 = "value2"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+In addition, the **config selector expressions** can be used to init a schema instance.
+
+```python
+person = {
+ base.count = 2
+ base.value = "value"
+ labels.key = "value"
+} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}}
+```
+
+We can **merge** dict using the dict unpacking operator `**` like this:
+
+```python
+_part1 = {
+ a = "b"
+}
+
+_part2 = {
+ c = "d"
+}
+
+a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"}
+```
+
+We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored.
+
+```python
+a = 1 # 1
+data = {
+ key1 = "value1"
+ if a == 1: key2 = "value2"
+ if a > 0: key3 = "value3"
+ if a < 0: key4 = "value4"
+} # {"key1": "value1", "key2": "value2", "key3": "value3"}
+```
+
+```python
+a = 1 # 1
+data1 = {
+ key1 = "value1"
+ if a == 1:
+ key2 = "value2"
+ elif a > 0:
+ key3 = "value3"
+ else:
+ key4 = "value4"
+} # {"key1": "value1", "key2": "value2"}
+data2 = {
+ key1 = "value1"
+ if a == 1: key2 = "value2"
+ elif a > 0: key3 = "value3"
+ else: key4 = "value4"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+### List Expressions
+
+A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression.
+
+```bnf
+list_expr: '[' [list_item [',']] ']'
+list_item: test | "*" primary_expr | if_expr
+```
+
+Element expressions are evaluated in left-to-right order.
+
+Examples:
+
+```python
+[] # [], empty list
+[1] # [1], a 1-element list
+[1, 2, 3] # [1, 2, 3], a 3-element list
+```
+
+We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored.
+
+```python
+a = 1 # 1
+data = [
+ 1
+ if a == 1: 2
+ if a > 0: 3
+ if a < 0: 4
+] # [1, 2, 3]
+```
+
+```python
+a = 1 # 1
+data1 = [
+ 1
+ if a == 1:
+ 2
+ elif a == 2:
+ 3
+ else:
+ 3
+] # [1, 2]
+data2 = [
+ 1
+ if a == 1: 2
+ elif a == 2: 2
+ else: 3
+] # [1, 2]
+```
+
+### Comprehensions
+
+A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result.
+
+Syntax:
+
+```bnf
+list_comp: '[' list_item comp_clause+ ']' .
+dict_comp: '{' entry comp_clause+ '}' .
+
+comp_clause: 'for' loop_variables [","] 'in' test ['if' test]
+loop_variables: primary_expr (',' primary_expr)*
+```
+
+A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements.
+
+Examples:
+
+```python
+[x * x for x in range(5)] # [0, 1, 4, 9, 16]
+[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16]
+[[x, y] for x in range(5) \
+ if x % 2 == 0 \
+ for y in range(5) \
+ if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]]
+```
+
+Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item.
+
+```python
+data = [1000, 2000, 3000]
+# Single variable loop
+dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000]
+dataLoop2 = [i for i in data if i == 2000] # [2000]
+dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000]
+# Double variable loop
+dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002]
+dataLoop5 = [v for i, v in data if v == 2000] # [2000]
+# Use `_` to ignore loop variables
+dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000]
+dataLoop7 = [i for i, _ in data] # [0, 1, 2]
+dataLoop8 = [v for _, v in data if v == 2000] # [2000]
+```
+
+A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable.
+
+Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key.
+
+```python
+data = {"key1" = "value1", "key2" = "value2"}
+# Single variable loop
+dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"}
+dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"}
+# Double variable loop
+dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"}
+dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"}
+dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"}
+# Use `_` to ignore loop variables
+dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"}
+dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"}
+```
+
+As with a `for` loop, the loop variables may exploit compound assignment:
+
+```python
+[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!']
+```
+
+KCL does not accept an un-parenthesized list as the operand of a for clause:
+
+```python
+[x * x for x in 1, 2, 3] # parse error: unexpected comma
+```
+
+Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block:
+
+```python
+x = 1
+_ = [x for x in [2]] # new variable x is local to the comprehension
+print(x) # 1
+```
+
+The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript.
+
+```python
+x0 = [1, 2, 3]
+[x * x for x in x0] # [1, 4, 9]
+[x * x for x in x0 if x % 2 == 0] # [4]
+```
+
+All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example:
+
+```python
+x0 = [[1, 2], [3, 4], [5, 6]]
+[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36]
+```
+
+which would be more clearly rewritten as:
+
+```python
+x = [[1, 2], [3, 4], [5, 6]]
+[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36]
+```
+
+### Conditional Expressions
+
+A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`.
+
+Syntax:
+
+```bnf
+if_expr: test "if" test "else" test
+```
+
+Examples:
+
+```python
+x = True if enabled else False # if enabled is
+```
+
+### Unary Expressions
+
+In KCL, supported unary operators are `+`, `-`, `~`, and `not`.
+
+Syntax:
+
+```bnf
+unary_expr: ("+" | "-" | "~") primary_expr
+ | "not" test
+```
+
+Usage:
+
+```bnf
++ number unary positive (int, float)
+- number unary negation (int, float)
+~ number unary bitwise inversion (int)
+not x logical negation (any type)
+```
+
+The `+` and `-` operators may be applied to any number (int or float) and return the number.
+The `not` operator returns the negation of the truth value of its operand.
+
+Examples:
+
+```python
+~1 # -2
+~-1 # 0
+~0 # -1
+not True # False
+not 0 # True
+```
+
+### Binary Expressions
+
+In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`.
+
+Syntax:
+
+```bnf
+binary_expr: test bin_op test
+bin_op: 'or'
+ | 'and'
+ | '==' | '!=' | '<' | '>' | '<=' | '>='
+ | 'in' | 'not' 'in'
+ | '|'
+ | '^'
+ | '&'
+ | '-' | '+'
+ | '*' | '%' | '/' | '//'
+ | '<<' | '>>'
+```
+
+#### Logical Operations
+
+The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans.
+
+The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise.
+
+```python
+False or False # False
+False or True # True
+True or True # True
+1 or "hello" # 1
+```
+
+Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise.
+
+```python
+False and False # False
+False and True # False
+True and True # True
+1 and "hello" # "hello"
+```
+
+These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these:
+
+```python
+x and x[0] == 1 # x[0] is not evaluated if x is empty
+len(x) == 0 or x[0] == ""
+not x or not x[0]
+```
+
+#### Comparisons
+
+The `==` operator reports whether its operands are equal; the `!=` operator is its negation.
+
+The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown:
+
+```bnf
+NoneType # None <= None
+bool # False < True
+int # mathematical
+float # as defined by IEEE 754
+string # lexicographical
+list # lexicographical
+```
+
+Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`.
+
+The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves.
+
+```bnf
+dict # equal contents
+schema # equal exported-attributes
+function # identity
+builtin_function_or_method # identity
+```
+
+#### Arithmetic Operations
+
+The following table summarizes the binary arithmetic operations available for built-in types:
+
+```bnf
+Arithmetic (int or float; result has type float unless both operands have type int)
+ number + number # addition
+ number - number # subtraction
+ number * number # multiplication
+ number / number # real division (result is always a float)
+ number // number # floored division
+ number % number # remainder of floored division
+ number ^ number # bitwise XOR
+ number << number # bitwise left shift
+ number >> number # bitwise right shift
+
+Concatenation
+ string + string
+ list + list
+
+Repetition (string/list)
+ int * sequence
+ sequence * int
+
+Union
+ int | int
+ list | list
+ dict | dict
+ schema | schema
+ schema | dict
+basictype | basictype
+```
+
+The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`.
+
+The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type.
+
+```python
+"Hello, " + "world" # "Hello, world"
+[1, 2] + [3, 4] # [1, 2, 3, 4]
+```
+
+The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero.
+
+```python
+'mur' * 2 # 'murmur'
+3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2]
+```
+
+The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands.
+
+The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**.
+
+Computing bitwise examples:
+
+```python
+0x12345678 | 0xFF # 0x123456FF
+```
+
+Unioning basic types examples:
+
+```python
+schema x:
+ a: int | str # attribute a could be a int or string
+```
+
+A union type is used to define a schema attribute type. See more details in **schema** spec.
+Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`.
+
+Unioning collection and schema data:
+
+- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**.
+
+```python
+_a = [1, 2, 3]
+_b = [4, 5, 6, 7]
+x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None
+```
+
+Unioning to the specific index or all elements is still under discussion.
+
+- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key**
+
+```python
+_a = {key1 = "value1"}
+_b = {key1 = "overwrite", key2 = "value2"}
+_c = _a | _b # {"key1": "overwrite", "key2": "value2"}
+```
+
+The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right.
+
+Unioning to the specific key or all keys is still under discussion.
+
+- Unioning Schema.
+
+The union operation for schema is similar to dict.
+
+Schema union could be done as:
+
+```bnf
+schema Person:
+ firstName: str
+ lastName: str
+
+_a = Person {
+ firstName = "John"
+}
+_b = {lastName = "Doe"}
+_a = _a | _b # {"firstName": "John", "lastName": "Doe"}
+```
+
+Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances.
+
+See **selector expression** in **expression** spec for more details.
+
+The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands.
+
+The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift.
+
+```python
+0x12345678 & 0xFF # 0x00000078
+0b01011101 ^ 0b110101101 # 0b111110000
+0b01011101 >> 2 # 0b010111
+0b01011101 << 2 # 0b0101110100
+```
+
+#### Membership Tests
+
+Usage:
+
+```bnf
+ any in sequence (list, dict, schema, string)
+ any not in sequence
+```
+
+The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean.
+
+The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings.
+
+```python
+1 in [1, 2, 3] # True
+
+d = {"one" = 1, "two" = 2}
+"one" in d # True
+"three" in d # False
+1 in d # False
+[] in d # False
+
+"nasty" in "dynasty" # True
+"a" in "banana" # True
+"f" not in "way" # True
+
+d = data {one = 1, two = 2} # data is a schema with attributes one and two
+"one" in d # True
+"three" in d # False
+```
+
+### Function Invocations
+
+KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion.
+
+Syntax:
+
+```bnf
+call_suffix: "(" [arguments [","]] ")"
+arguments: argument ("," argument)*
+argument: test | identifier "=" test | "*" test | "**" test
+```
+
+To call a function, the basic way is shown as the following code excerpt:
+
+```python
+print("An argument")
+
+import math
+# 2 powers 3 is 8.
+a = math.pow(2, 3)
+```
+
+As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments.
+
+Note that:
+
+- Some functions have parameters with default values.
+- Some functions accept variadic arguments.
+
+When an argument is not supplied for a parameter without a default value,
+an error will be reported.
+
+### Selector Expressions
+
+A selector expression selects the attribute or method of the value.
+
+#### Select Attributes
+
+Syntax:
+
+```bnf
+select_suffix: ["?"] "." identifier
+```
+
+KCL provides a wealth of ways to identify or filter attributes.
+
+x.y
+
+- schema: it denotes the attribute value of a schema `x` identified by `y`
+- package: it denotes the identifier of a package `x` identified by `y`
+
+Examples:
+
+```python
+schema Person:
+ name: str
+ age: int
+
+person = Person {
+ name = "Alice"
+ age = 18
+}
+name = person.name # "Alice"
+age = person.age # 18
+```
+
+x?.y
+
+If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y.
+
+Examples
+
+```python
+noneData = None
+data?.name # None
+
+emptyDict = {}
+emptyDict?.name # None
+
+emptyList = []
+emptyList?[0] # None
+```
+
+As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form.
+
+#### Select Methods
+
+Syntax:
+
+```bnf
+select_suffix: "." identifier
+```
+
+A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`.
+
+- A selector expression fails if the value does not have an attribute of the specified name.
+- A selector expression that selects a method typically appears within a call expression, as in these examples:
+
+Examples:
+
+```python
+["able", "baker", "charlie"].index("baker") # 1
+"banana".count("a") # 3
+"banana".reverse() # error: string has no .reverse field or method
+Person.instances() # all instances of schema Person
+```
+
+But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument:
+
+```bnf
+f = "banana".count
+f #
+f("a") # 3
+f("n") # 2
+```
+
+### Index Expressions
+
+An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error.
+
+Syntax:
+
+```bnf
+subscript_suffix: "[" [test] "]"
+```
+
+A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence.
+
+```python
+"abc"[0] # "a"
+"abc"[1] # "b"
+"abc"[-1] # "c"
+
+["zero", "one", "two"][0] # "zero"
+["zero", "one", "two"][1] # "one"
+["zero", "one", "two"][-1] # "two"
+```
+
+An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key.
+
+An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated:
+
+```python
+a = range(3) # a == [0, 1, 2]
+b = a[2] # 2
+
+
+```
+
+It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type.
+
+### Slice Expressions
+
+A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list.
+
+```bnf
+subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]"
+```
+
+Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer.
+The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero.
+
+Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.`
+
+The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence.
+
+**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive.
+
+**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive.
+
+```python
+"abc"[1:] # "bc" (remove first element)
+"abc"[:-1] # "ab" (remove last element)
+"abc"[1:-1] # "b" (remove first and last element)
+"banana"[1::2] # "aaa" (select alternate elements starting at index 1)
+"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4)
+```
+
+It's not allowed to define a slice expression as a left value in KCL.
+Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance.
+
+#### Quantifier Expressions
+
+Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms:
+
+```bnf
+quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}'
+quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp
+quant_op: 'all' | 'any' | 'filter' | 'map'
+```
+
+- **all**
+ - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result.
+ - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false.
+ - If the original collection is empty, return true.
+ - Supports short-circuiting of logical expressions during expression execution.
+- **any**
+ - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result.
+ - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false.
+ - If the original collection is empty, return false.
+ - Supports short-circuiting of logical expressions during expression execution.
+- **map**
+ - Generate a new **list** by mapping the elements in the original collection.
+ - The length of the new list is exactly the same as the original collection.
+- **filter**
+ - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection.
+ - Only when the element judges the expression to be true, it is added to the sub-collection.
+ - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`.
+
+**all** and **any** expression sample codes:
+
+```python
+schema Config:
+ volumes: [{str:}]
+ services: [{str:}]
+
+ check:
+ all service in services {
+ service.clusterIP == "NONE" if service.type == "ClusterIP"
+ }, "invalid cluster ip"
+
+ any volume in volumes {
+ volume.mountPath in ["/home/admin", "/home/myapp"]
+ }
+```
+
+**map** and **filter** expression sample codes:
+
+```python
+a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] {
+ {name = e.name, value = int(e.value) ** 2}
+} # [{"name": "1", value: 1}, {"name": "2", "value": 4}]
+
+b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"]
+
+c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] {
+ int(e.value) > 1
+} # [{"name": "2", "value": 2}]
+
+d = filter _, v in {a = "foo", b = "bar"} {
+ v == "foo"
+} # {"a": "foo"}
+```
+
+Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/index.md
new file mode 100644
index 000000000..c3ecc1626
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/index.md
@@ -0,0 +1 @@
+# KCL 语言规范
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/kcl-spec.md
new file mode 100644
index 000000000..26e22eea7
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/kcl-spec.md
@@ -0,0 +1,339 @@
+---
+title: "KCL Spec"
+linkTitle: "KCL Spec"
+type: "docs"
+weight: 2
+description: KCL Spec
+---
+
+## Lexical rules
+
+### Keywords and reserved words
+
+The following are the keywords of the KCL:
+
+```python
+True False None Undefined import
+and or in is not
+as if else elif for
+schema mixin protocol check assert
+all any map filter lambda
+rule
+```
+
+The following are reserved words for the KCL:
+
+```python
+pass return validate rule flow
+def del raise except try
+finally while from with yield
+global nonlocal struct class final
+```
+
+### Line comment
+
+```python
+# a comment
+```
+
+### Operators
+
+```python
++ - * ** / // %
+<< >> & | ^ < >
+~ <= >= == != =
++= -= *= **= /= //= %=
+<<= >>= &= ^=
+```
+
+### Delimiters
+
+```python
+( ) [ ] { }
+, : . ; @
+```
+
+### Operator precedence
+
+The following list of operators is ordered from **highest to lowest**:
+
+| Operator | Description |
+| -------------------------------------------------------------------------------- | -------------------------------------------------------- |
+| `**` | Exponentiation (highest priority) |
+| `+x` `-x` `~x` | Positive, negative, bitwise NOT |
+| `*` `/` `%` `//` | Multiplication, division, floor division and remainder |
+| `+` `-` | Addition and subtraction |
+| `<<` `>>` | Left and right shifts |
+| `&` | Bitwise AND |
+| `^` | Bitwise XOR |
+| \| | Bitwise OR |
+| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators |
+| `not` | Boolean NOT |
+| `and` | Boolean AND |
+| `or` | Boolean OR |
+| `if – else` | Conditional expression = |
+| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign |
+
+## Grammar
+
+KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows:
+
+```bnf
+//////////// KCL grammar ////////////
+start: (NEWLINE | statement)*
+
+statement: simple_stmt | compound_stmt
+simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE
+compound_stmt: if_stmt | schema_stmt | rule_stmt
+
+//////////// import_stmt ////////////
+import_stmt: IMPORT dot_name (AS NAME)?
+dot_name: (leading_dots identifier) | identifier
+leading_dots: DOT+
+
+/////////// assert_stmt ////////////
+assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)?
+
+//////////// if_stmt ////////////
+if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)?
+execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT
+if_simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE
+
+//////////// assign_stmt ////////////
+assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test
+ | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE
+ | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT
+ | COMP_SHIFT_RIGHT) test
+
+//////////// unification_stmt ////////////
+unification_stmt: identifier COLON schema_expr
+
+//////////// schema_stmt ////////////
+schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body]
+schema_arguments: schema_argument (COMMA schema_argument)*
+schema_argument: NAME [COLON type] [ASSIGN test]
+schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT
+schema_attribute_stmt: attribute_stmt NEWLINE
+attribute_stmt: [decorators] (identifier | STRING) [QUESTION] COLON type [(ASSIGN|COMP_OR) test]
+schema_init_stmt: if_simple_stmt | if_stmt
+schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE
+
+//////////// rule_stmt ////////////
+rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body]
+rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT
+
+for_host: FOR identifier
+
+/////////// decorators ////////////
+decorators: (AT decorator_expr NEWLINE)+
+decorator_expr: identifier [call_suffix]
+
+//////////// type ////////////
+type: type_element (OR type_element)*
+type_element: schema_type | function_type | basic_type | compound_type | literal_type
+schema_type: identifier
+function_type: LEFT_PARENTHESES [type_element (COMMA type_element)*] RIGHT_PARENTHESES [RIGHT_ARROW type_element]
+basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE
+compound_type: list_type | dict_type
+list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS
+dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE
+literal_type: string | number | TRUE | FALSE
+
+//////////// type alias ////////////
+type_alias_stmt: TYPE NAME ASSIGN type
+
+//////////// check_stmt ////////////
+check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT
+check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE
+
+//////////// mixin_stmt ////////////
+mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE
+multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT
+mixins: identifier (COMMA (NEWLINE mixins | identifier))*
+
+
+//////////// expression_stmt ////////////
+expr_stmt: testlist_expr
+testlist_expr: test (COMMA test)*
+test: if_expr | simple_expr
+if_expr: simple_expr IF simple_expr ELSE test
+
+simple_expr: unary_expr | binary_expr | primary_expr
+
+unary_expr: un_op simple_expr
+binary_expr: simple_expr bin_op simple_expr
+
+bin_op: L_OR | L_AND
+ | OR | XOR | AND
+ | SHIFT_LEFT | SHIFT_RIGHT
+ | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE
+ | DOUBLE_STAR
+ | EQUAL_TO | NOT_EQUAL_TO
+ | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO
+ | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS
+un_op: L_NOT | PLUS | MINUS | NOT
+
+primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix
+operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES
+select_suffix: [QUESTION] DOT NAME
+call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES
+slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS
+arguments: argument (COMMA argument)*
+argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test
+
+
+//////////// operand ////////////
+identifier: NAME (DOT NAME)*
+quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE
+quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp
+quant_op: ALL | ANY | FILTER | MAP
+list_expr: LEFT_BRACKETS [list_items | NEWLINE [list_items]] RIGHT_BRACKETS
+list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE]
+list_item: test | star_expr | if_item
+list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE list_item comp_clause) RIGHT_BRACKETS
+dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE entry comp_clause+) RIGHT_BRACE
+entry: test (COLON | ASSIGN | COMP_PLUS) test
+comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]]
+if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)?
+if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT
+if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)?
+if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT
+
+star_expr: MULTIPLY test
+double_star_expr: DOUBLE_STAR test
+loop_variables: primary_expr (COMMA primary_expr)*
+schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr
+config_expr: LEFT_BRACE [config_entries | NEWLINE [config_entries]] RIGHT_BRACE
+config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE]
+config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry
+
+//////////// lambda_expr ////////////
+lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE
+
+//////////// misc ////////////
+number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER
+multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P
+ | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC
+string: STRING | LONG_STRING
+constant : TRUE | FALSE | NONE | UNDEFINED
+
+// Tokens
+ASSIGN: "="
+COLON: ":"
+SEMI_COLON: ";"
+COMMA: ","
+QUESTION: "?"
+ELLIPSIS: "..."
+RIGHT_ARROW: "->"
+LEFT_PARENTHESES: "("
+RIGHT_PARENTHESES: ")"
+LEFT_BRACKETS: "["
+RIGHT_BRACKETS: "]"
+LEFT_BRACE: "{"
+RIGHT_BRACE: "}"
+PLUS: "+"
+MINUS: "-"
+MULTIPLY: "*"
+DIVIDE: "/"
+MOD: "%"
+DOT: "."
+AND: "&"
+OR: "|"
+XOR: "^"
+NOT: "~"
+LESS_THAN: "<"
+GREATER_THAN: ">"
+EQUAL_TO: "=="
+NOT_EQUAL_TO: "!="
+GREATER_THAN_OR_EQUAL_TO: ">="
+LESS_THAN_OR_EQUAL_TO: "<="
+DOUBLE_STAR: "**"
+DOUBLE_DIVIDE: "//"
+SHIFT_LEFT: "<<"
+SHIFT_RIGHT: ">>"
+AT: "@"
+
+COMP_PLUS: "+="
+COMP_MINUS: "-="
+COMP_MULTIPLY: "*="
+COMP_DIVIDE: "/="
+COMP_MOD: "%="
+COMP_AND: "&="
+COMP_OR: "|="
+COMP_XOR: "^="
+COMP_DOUBLE_STAR: "**="
+COMP_DOUBLE_DIVIDE: "//="
+COMP_SHIFT_LEFT: "<<="
+COMP_SHIFT_RIGHT: ">>="
+
+// Special tokens
+IMPORT: "import"
+AS: "as"
+RULE: "rule"
+SCHEMA: "schema"
+MIXIN: "mixin"
+PROTOCOL: "protocol"
+CHECK: "check"
+FOR: "for"
+ASSERT: "assert"
+IF: "if"
+ELIF: "elif"
+ELSE: "else"
+L_OR: "or"
+L_AND: "and"
+L_NOT: "not"
+IN: "in"
+IS: "is"
+LAMBDA: "lambda"
+ALL: "all"
+ANY: "any"
+FILTER: "filter"
+MAP: "map"
+TYPE: "type"
+
+ANY_TYPE: "any"
+STRING_TYPE: "str"
+INT_TYPE: "int"
+FLOAT_TYPE: "float"
+BOOL_TYPE: "bool"
+
+// Constant tokens
+TRUE: "True"
+FALSE: "False"
+NONE: "None"
+UNDEFINED: "Undefined"
+
+// Binary prefix
+SI_N_L: "n"
+SI_U_L: "u"
+SI_M_L: "m"
+SI_K_L: "k"
+SI_K: "K"
+SI_M: "M"
+SI_G: "G"
+SI_T: "T"
+SI_P: "P"
+SI_K_IEC: "Ki"
+SI_M_IEC: "Mi"
+SI_G_IEC: "Gi"
+SI_T_IEC: "Ti"
+SI_P_IEC: "Pi"
+IEC: "i"
+
+NAME: /\$?[a-zA-Z_]\w*/
+COMMENT: /#[^\n]*/
+NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+
+
+STRING: /r?("(?!"").*?(? **note**
+>
+> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character.
+
+- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards).
+- A backslash does not continue a comment.
+- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash).
+- A backslash is illegal elsewhere on a line outside a string literal.
+
+### Implicit Line Joining
+
+Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes.
+
+- Implicitly continued lines can carry comments.
+- The indentation of the continuation lines is not important.
+- Blank continuation lines are allowed.
+- There is no `NEWLINE` token between implicit continuation lines.
+- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments.
+
+### Blank Lines
+
+### Indentation
+
+### Comments
+
+Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line.
+
+A comment signifies the end of the logical line unless the implicit line joining rules are invoked.
+
+Comments are ignored by the syntax.
+
+### Identifiers and Keywords
+
+Identifiers (also referred to as names) are described by the following lexical definitions.
+
+Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`.
+
+Identifiers are unlimited in length. The case is significant.
+
+### Keywords
+
+The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here:
+
+```python
+True False None Undefined import
+and or in is not
+as if else elif for
+schema mixin protocol check assert
+all any map filter lambda
+rule
+```
+
+The following tokens are not used, but they are reserved as possible future keywords:
+
+```python
+pass return validate rule flow
+def del raise except try
+finally while from with yield
+global nonlocal struct class final
+```
+
+### Literals
+
+Literals are notations for constant values of some built-in types.
+
+### String Literals
+
+String literals are described by the following lexical definitions:
+
+```
+stringliteral ::= [stringprefix](shortstring | longstring)
+stringprefix ::= "r" | "R"
+shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"'
+longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
+shortstringitem ::= shortstringchar | stringescapeseq
+longstringitem ::= longstringchar | stringescapeseq
+shortstringchar ::=
+longstringchar ::=
+stringescapeseq ::= "\"
+```
+
+Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation.
+
+### Numeric Literals
+
+There are two types of numeric literals: integers and floating-point numbers.
+
+Integer literals are described by the following lexical definitions:
+
+```
+integer ::= decinteger | bininteger | octinteger | hexinteger
+decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")*
+bininteger ::= "0" ("b" | "B") (["_"] bindigit)+
+octinteger ::= "0" ("o" | "O") (["_"] octdigit)+
+hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+
+nonzerodigit ::= "1"..."9"
+digit ::= "0"..."9"
+bindigit ::= "0" | "1"
+octdigit ::= "0"..."7"
+hexdigit ::= digit | "a"..."f" | "A"..."F"
+```
+
+Floating-point literals are described by the following lexical definitions:
+
+```
+floatnumber ::= pointfloat | exponentfloat
+pointfloat ::= [digitpart] fraction | digitpart "."
+exponentfloat ::= (digitpart | pointfloat) exponent
+digitpart ::= digit (["_"] digit)*
+fraction ::= "." digitpart
+exponent ::= ("e" | "E") ["+" | "-"] digitpart
+```
+
+## Operators and Delimiters
+
+### Operators
+
+The following tokens are operators:
+
+```python
++ - * ** / // %
+<< >> & | ^ < >
+~ <= >= == != @
+```
+
+### Delimiters
+
+The following tokens serve as delimiters in the grammar:
+
+```python
+( ) [ ] { }
+, : . ; = +=
+-= *= **= /= //= %=
+<<= >>= &= |= ^=
+```
+
+The period can also occur in floating-point literals.
+
+The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer:
+
+```
+' " # \
+```
+
+The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error:
+
+```
+? `
+```
+
+## Reference
+
+Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter.
+
+- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html)
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/modules.md
new file mode 100644
index 000000000..2f54a281d
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/modules.md
@@ -0,0 +1,350 @@
+---
+title: "Modules"
+linkTitle: "Modules"
+type: "docs"
+weight: 2
+description: Modules
+---
+
+## Modules and the Import System
+
+KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used.
+
+Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled.
+
+A regular KCL module is a file on the file system. It is required to have a `.k` suffix.
+
+## Packages
+
+To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file.
+
+Files directly under a package are considered parts of the package, instead of individual regular modules.
+
+Packages can have sub-packages.
+
+Packages are special modules:
+
+- All packages in KCL are modules.
+- A single-file module can never be a package.
+
+All modules have a name.
+
+Sub package names are separated from their parent package name by dots.
+
+To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath.
+
+### Intra-Package Name Space Sharing
+
+Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted.
+
+### Package Initialization
+
+A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions.
+
+## Searching
+
+The searching begins when an `import` statement is used to import a module.
+
+### Module Cache
+
+In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory.
+
+However, other modules are uncached. Importing a module multiple time would create multiple instances of the module.
+
+### Module Names
+
+An `import` statement specifies the name of the module to import. The syntax is:
+
+```
+import [as ]
+```
+
+The rule to search with the module name is very simple:
+
+- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**.
+ - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**.
+- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**.
+- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists.
+ - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**.
+- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**.
+- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule:
+- One dot: Ignore.
+- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**.
+- **Step 6**. Module not found, report an error.
+
+Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files.
+
+In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax.
+
+### Uniqueness of Module
+
+Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`.
+
+Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form.
+
+## Standard System Packages
+
+KCL supports a few standard system modules. [Here](docs/reference/model/overview) is the full list of these standard system modules.
+
+### The Built-in System Package
+
+KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module.
+
+The following is the full list of these built-in system modules:
+
+- print()
+ - The print function.
+- multiplyof(a, b)
+ - Check if the modular result of a and b is 0
+- isunique(inval)
+ - Check if a list has duplicated elements
+- len(inval)
+ Return the length of a value
+- abs(x)
+ Return the absolute value of the argument.
+- all(iterable)
+ Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True.
+- any(iterable)
+ Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False.
+- bin(number)
+ Return the binary representation of an integer.
+- hex(number)
+ Return the hexadecimal representation of an integer.
+- oct(number)
+ Return the octal representation of an integer.
+- ord(c) -> int
+ Return the Unicode code point for a one-character string.
+- sorted(iterable)
+ Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order.
+- range(start, end, step=1)
+ Return the range of a value with start, end and step parameter.
+- min(iterable)
+ With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument.
+- max(iterable)
+ With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument.
+- sum(iterable, start)
+ Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types.
+- pow(x, y, z)
+ Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form.
+- round(number, ndigits)
+ Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative.
+- typeof(x: any, \*, full_name: bool = False) -> str
+ Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`.
+
+### Plugin Modules
+
+KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing.
+
+KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler.
+
+Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored.
+
+Importing and using the extended plugin module should be consistent with the standard or built-in system module.
+
+### Replacing Standard System Packages
+
+Replacing standard system modules is not allowed.
+
+## Examples
+
+We show more module features through an example.
+
+Suppose we have the following directories and files:
+
+```
+ .
+ ├── mod1.k
+ ├── mod2.k
+ ├── pkg1
+ │ ├── def1.k
+ │ ├── def2.k
+ │ └── def3init.k
+ └── pkg2
+ ├── file2.k
+ └── subpkg3
+ └── file3.k
+```
+
+From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules.
+
+### Importing a Standard System Package
+
+The following statement can import the standard system module `math`
+
+```python
+import math
+```
+
+This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function
+defined in `math`
+
+```python
+a = math.log10(100) # a is 2 after computation.
+```
+
+### Importing a Regular Module
+
+In `mod1.k`, we can import `mod2` using one of the following syntaxes.
+
+```python
+import mod2
+```
+
+```python
+import .mod2
+```
+
+The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does.
+
+Suppose in `mod2.k` there is a definition of a variable::
+
+```python
+a = 100
+```
+
+After importing `mod2`, we can access `a` in `mod1.k` using the following syntax
+
+```python
+b = mod2.a
+```
+
+### Importing a Package
+
+In `mod1.k`, we can import `pkg1` using one of the following syntaxes.
+
+```python
+import pkg1
+```
+
+```python
+import .pkg1
+```
+
+The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does.
+
+We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`.
+
+The name of the package is the name of the imported module.
+
+Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo`
+
+```python
+foo = 100
+```
+
+This variable can be used in `mod1.k` after importing `pkg2` like the following
+
+```python
+bar = pkg2.foo
+```
+
+### Importing a Subpackage
+
+To import `subpkg3` from `mod1.k`, one of the following statements can be used.
+
+```python
+import pkg2.subpkg3
+```
+
+```python
+import .pkg2.subpkg3
+```
+
+The behaviors of these statements are identical.
+
+The name of the subpackage is the name of the imported module.
+
+Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo`
+
+```python
+foo = 100
+```
+
+This variable can be used in `mod1.k` after importing `subpkg3` like the following
+
+```python
+bar = subpkg3.foo
+```
+
+### Relative Importing
+
+Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory.
+
+For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively.
+
+```python
+import ...pkg2 # Go two levels up then import pkg2
+import ...pkg1 # Go two levels up then import pkg1
+import ...mod2 # Go two levels up then import mod2
+```
+
+### Importing from a Root Path
+
+Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files:
+
+```
+ .
+ |── kcl.mod
+ ├── mod1.k
+ ├── mod2.k
+ ├── pkg1
+ │ ├── def1.k
+ │ ├── def2.k
+ │ └── def3init.k
+ └── pkg2
+ ├── file2.k
+ └── subpkg3
+ └── file3.k
+```
+
+In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes.
+
+```python
+import pkg2.subpkg3.file3
+```
+
+Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory.
+
+### Importing a Module Inside a Package
+
+Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly.
+
+In `mod1.k`, the importing statement would be::
+
+```python
+import pkg2.subpkg3.file3
+```
+
+Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following
+statement
+
+```python
+bar = file3.foo
+```
+
+### Precedence of Importing
+
+When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system.
+
+If such a directory is not found, the virtual machine looks for a single file module.
+
+For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported.
+
+### Package Implemented with Multiple Files
+
+Package `pkg1` is implemented with multiple KCL files.
+
+Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package.
+
+For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used
+
+```python
+import pkg1
+a = pkg1.foo + pkg1.bar + pkg1.baz
+```
+
+Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following
+
+```python
+bar = foo + 1
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/schema.md
new file mode 100644
index 000000000..545f2e6bf
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/schema.md
@@ -0,0 +1,916 @@
+---
+title: "Schema"
+linkTitle: "Schema"
+type: "docs"
+weight: 2
+description: Schema
+---
+
+## Syntax
+
+### Schema Definition
+
+A schema is a language element to define a type of configuration data.
+
+To define a schema, the syntax is the following:
+
+```bnf
+schema_stmt: [decorators] "schema" identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body]
+schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT
+```
+
+Attributes could be defined in a schema, the syntax is the following:
+
+```bnf
+schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE
+```
+
+Index signature could be defined in a schema, the syntax is the following:
+
+```bnf
+schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE
+```
+
+Once defined, an attribute must have a valid type:
+
+```bnf
+type: type_element ("|" type_element)*
+type_element: schema_type | basic_type | list_type | dict_type
+schema_type: operand_name
+basic_type: "str" | "int" | "float" | "bool"
+list_type: "[" (type)? "]"
+dict_type: "{" (type)? COLON (type)? "}"
+```
+
+The followings are some basic examples:
+
+```python
+# A person has a first name, a last name and an age.
+schema person:
+ firstName: str
+ lastName: str
+ # fullName is generated by firstName and lastName
+ fullName: str = firstName + ' ' + lastName
+ # The default value of age is 0
+ age: int = 0
+
+# An employee IS a person, and has some additional information.
+schema employee(person):
+ bankCard: int
+ nationality: str
+
+# A company has a name and many employees.
+schema company:
+ name: str
+ employees: [employee]
+```
+
+More complex schema definitions will be elaborated after other concepts are
+introduced.
+
+#### Optional Attribute
+
+Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute.
+
+Examples:
+
+```bnf
+schema employee(person):
+ bankCard?: int # bankCard is an optional attribute
+ nationality?: str # # nationality is an optional attribute
+```
+
+When there is an inheritance relationship:
+
+- If the attribute is optional in the base schema, it could be optional or required in the sub-schema.
+- If the attribute is required in the base schema, it must be required in the sub-schema.
+
+### Configuration Definition
+
+A configuration is structured data stored in a dict-like structure. In KCL, we have introduced
+the configuration definition syntax as a variant of dict definition syntax.
+
+```bnf
+schema_expr: operand_name ("(" [arguments] ")")? dict_expr
+```
+
+As can be seen, apart from having an identifier as schema type, a configuration definition
+is just an ordinary dict definition, and each key in the dict matches an attribute in the schema.
+
+To simplify configuration, schema attribute key is much easier to define as:
+
+- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict.
+- schema attribute key can be defined nested through `select expression`, such as `a.b.c`.
+
+The comma at the end of each line can be omitted.
+
+For example, we can define a `person` named `John Doe` using the following statement:
+
+```python
+johnDoe = person {
+ # In the result, 'lastName' appears later than 'firstName', according the schema
+ lastName = 'Doe'
+ firstName = 'John'
+ # If we don't specify the 'age', the default value 0 is used.
+ # 'age': 20
+}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'firstName': 'John'
+ 'lastName': 'Doe'
+ 'age': 0
+}
+```
+
+Compared to the ordinary dict definition, a configuration definition has the following features:
+
+- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value.
+- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used.
+- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined.
+- The quotation marks of dict key can be omitted.
+- The comma at the end of each line can be omitted.
+- Cases of **inheritance** will be discussed separately.
+
+For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance:
+
+```python
+schema Name:
+ firstName: str
+ lastName: str
+
+schema Person:
+ name: Name = {
+ firstName = "John"
+ lastName = "default"
+ }
+
+JohnDoe = Person {
+ name.lastName = "Doe"
+}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'firstName': 'John'
+ 'lastName': 'Doe'
+}
+```
+
+#### Attribute Identify
+
+Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema:
+
+```python
+
+schema C:
+ c: int
+
+schema B:
+ b: C
+
+schema A:
+ a: B
+
+A {
+ a.b.c: 5
+}
+```
+
+To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows.
+
+##### List
+
+Suppose we have a list attribute a.
+
+Identify an element in a:
+
+```python
+a[0] # the first element
+a[3] # the 4th element
+a[-1] # the last element
+a[-2] # the penultimate element
+```
+
+Identify a range of elements in the list:
+
+```python
+a[2:5] # a slice of the third, 4th, and 5th elements
+a[:5] # a slice of the first to 5th elements
+```
+
+#### Attribute Operator
+
+Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`.
+
+#### Union
+
+Pattern: `identifier : E`
+
+The value of the expression `E` will be unioned into the element value.
+
+Examples:
+
+```python
+a = A {
+ # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d.
+ b.c : {
+ d : 4
+ }
+}
+```
+
+See 'union' in `expressions` spec for more details.
+
+#### Override
+
+Pattern: `identifier = E`
+
+The value of the expression `E` will override the element value.
+
+Examples:
+
+```python
+a = A {
+ # override {c:4} to the element b, suppose b is a schema with an int type attribute c.
+ b = {
+ c: 4
+ }
+}
+```
+
+Unlike union, the override operation will reassign the element with a brand new value.
+For basic type value, `union` and `override` have equivalent effects.
+
+Note:
+
+- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`.
+
+#### Insert
+
+Pattern: `identifier += E`
+Insert only works for list type `identifier`.
+
+List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted.
+
+Examples:
+
+```python
+a = A {
+ # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c.
+ b += {
+ c: 4
+ }
+}
+```
+
+If no index is specified, the last index will be used.
+
+The type of 'E' must be compatible with the type of list. See `types` for more details.
+
+#### Index Signature
+
+Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks.
+
+- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted.
+
+```python
+schema Map:
+ """
+ Map is a relaxed schema with a key of str type and a value of str type
+ """
+ [str]: str # `{attr_alias}` can be omitted.
+
+data = Map {
+ key1 = "value1"
+ key2 = "value2"
+}
+```
+
+- Mandatory all attributes of the schema key and value types
+
+```python
+schema Person:
+ name: str
+ age: int # error, conflicts with the index signature definition `[str]: str`
+ [str]: str # The values of all attributes of the schema can only be strings
+```
+
+- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes.
+
+```python
+schema Person:
+ name: str
+ age: int
+ [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`.
+```
+
+- Define the index signature attribute alias and use it with the check block.
+
+```python
+schema Data:
+ [dataName: str]: str
+ check:
+ dataName in ["Alice", "Bob", "John"]
+
+data = Data {
+ Alice = "10"
+ Bob = "12"
+ Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"]
+}
+```
+
+```python
+import regex
+
+schema DataMap:
+ [attr: str]: str
+ check:
+ regex.match(attr, r'^[-_a-zA-Z0-9]+$')
+
+data = DataMap {
+ key1 = "value1"
+ "foo.bar" = "value2" # check error
+}
+```
+
+### Schema Context
+
+The schema definition space can be regarded as a separate function context.
+
+Init statement could be defined inside the schema, the syntax is the following:
+
+```bnf
+statement: small_stmt NEWLINE | if_stmt
+```
+
+The following is an example:
+
+```python
+schema Person:
+ firstName: str = "John"
+ lastName: str
+ # fullName is generated by firstName and lastName in a separate init statement
+ fullName: str = firstName + ' ' + lastName
+
+JohnDoe = Person {
+ lastName = "Doe"
+}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'firstName': 'John'
+ 'lastName': 'Doe'
+ 'fullName': 'John Doe'
+}
+```
+
+If statement, expr statement and assert statement are supported as a schema init
+statement. See more in statement spec.
+
+- The attributes must be defined first, including inherited ones, and then used in the init statement.
+- Statements in the schema context will be executed sequentially.
+- The value of attributes referenced in the init statement will be evaluated at runtime.
+ See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe".
+
+The immutability of attributes in the schema context follows the same rules as the immutability of global variables:
+
+```python
+schema Person:
+ age: int = 1 # Immutable attribute
+ _name: str = "Alice" # Mutable attribute
+
+ age = 10 # Error
+ _name = "Bob" # Ok
+```
+
+#### Arguments
+
+Schema context can also have arguments. The following is an example.
+
+```python
+schema Person[separator]:
+ firstName: str = "John"
+ lastName: str
+ fullName: str = firstName + separator + lastName
+
+JohnDoe = Person('_') {
+ lastName = "Doe"
+}
+```
+
+The example is similar to the previous one, except that the separator character used in
+the `"fullName"` member is passed in as an argument. The way to perform a schema generation
+when the schema has an initialization function with arguments is demonstrated in the code.
+
+### Check Block
+
+Optionally, a check block can be added to a schema definition to allow
+additional checking to be performed.
+
+The syntax is the following:
+
+```bnf
+check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT
+check_expr: test (IF test)? [":" primary_expr] NEWLINE
+```
+
+In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example:
+
+```python
+schema employee(person):
+ bankCard: int
+ gender: str
+
+ check:
+ len(str(bankCard)) == 16
+ gender in ['male', 'female'], "The gender {} is unsupported".format(gender)
+```
+
+The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec.
+Whether to support `lambda expressions` is still under discussion.
+
+Summary:
+
+- A check block consists of one or more logical **expressions**.
+- When defining a configuration, the expressions in the check block are evaluated
+ in any order. If any of the expression is `False`, an error is reported.
+- A custom error message can be provided after an expression.
+
+### Specifying Types
+
+Optionally, the type of any member of a schema can be specified. As previous examples have shown.
+
+A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`).
+
+A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name.
+
+A member can also be a list or an ordinary dict:
+
+- A list with unspecified type of elements is `[]`.
+- A list with elements of type `t` is `[t]`. Here `t` is another type.
+- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`.
+- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements.
+
+The followings are some more examples:
+
+- A list of lists of strings: `[[str]]`.
+- A dict of keys with the type string and unspecified value types: `{str:}`.
+
+A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b.
+
+A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc.
+
+Examples:
+
+```python
+schema x:
+ p: int | str # p could be defined as a int or string
+```
+
+### Immutability
+
+KCL pursues strict immutability of schema attributes. It's generally followed the rules:
+
+- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned
+ through the init statement in **schema context** or by the **configuration definition**.
+- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**.
+- Any other attempt to reassign or modify schema attribute will report an error.
+
+#### Assign by Value
+
+When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable.
+
+```python
+schema Person:
+ name: str
+
+person = {
+ name = "Alice"
+}
+personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person'
+```
+
+### Union Operator
+
+For list, dict and schema, we can union delta to existing data. For example:
+
+```python
+schema Name:
+ firstName: str
+ lastName: str
+
+schema Person:
+ name: Name = {
+ firstName = "John"
+ }
+
+ # union a schema and a dict
+ name: Name {
+ lastName = "Doe"
+ }
+
+person = Person {}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'person': {
+ 'name': {
+ 'firstName': 'Jhon',
+ 'lastName': 'Doe'
+ }
+ }
+}
+```
+
+### Other Operators
+
+Except for `assignment` and `union assignment`, it's not support other operators on schema type data.
+Report an error if trying to use other operators on schema type data.
+
+### Deprecated
+
+The schema attribute can be marked as deprecated once it's considered invalid.
+
+```python
+schema Person:
+ @deprecated(version="1.1.0", reason="use fullName instead", strict=True)
+ name: str
+ ... # Omitted contents
+
+person = Person {
+ # report an error on configing a deprecated attribute
+ name = "name"
+}
+```
+
+- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned.
+- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**.
+- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment.
+
+### Composition
+
+The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures.
+
+Assuming we have the following schemas, which is defined by a combination of multiple schemas.
+
+```python
+schema Name:
+ firstName: str
+ lastName: str
+
+schema Person:
+ name: Name
+ age: int
+
+schema Group:
+ name: str
+ persons: [Person]
+```
+
+To config a group:
+
+```python
+group = Group {
+ name = "group"
+ persons = [{
+ name = {
+ firstName = "John"
+ lastName = "Doe"
+ }
+ age = 24
+ }]
+}
+```
+
+- Top-level schema name is required to config a schema.
+- The schema of the attributes in the schema can be omitted.
+
+Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example:
+
+```python
+group = Group {
+ name = "group"
+ persons = [{
+ name.firstName = "John"
+ name.lastName = "Doe"
+ age = 24
+ }]
+}
+```
+
+- Selector can be used to represent attribute in a schema
+
+### Inheritance
+
+Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema.
+
+```python
+schema Person:
+ firstName: str
+ lastName: str
+
+# schema Scholar inherits schema Person
+schema Scholar(Person):
+ fullName: str = firstName + '_' + lastName
+ subject: str
+
+JohnDoe = Scholar {
+ firstName = "John",
+ lastName = "Doe",
+ subject = "CS"
+}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'JohnDoe': {
+ 'firstName': 'John'
+ 'lastName': 'Doe'
+ 'fullName': 'John Doe'
+ 'subject': 'CS'
+ }
+}
+```
+
+Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema.
+
+The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example:
+
+```python
+schema a:
+ x = 1
+ y = x * 2
+
+schema b(a):
+ x = 2
+
+v = a {
+ x = 3
+}
+
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'v': {
+ 'x': 3
+ 'y': 6
+ }
+}
+```
+
+Notes:
+
+- Report an error if inheriting more than one base schema.
+- The type of the base schema attribute cannot be modified in the subschema.
+- Report an error if inheriting a **mixin**.
+- Report an error when a circular dependency occurs.
+
+Limitations:
+
+Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion.
+
+- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition.
+- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block.
+- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema.
+
+### Mixin
+
+In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition.
+
+The **mixin** syntax is the following:
+
+```bnf
+//////////// mixin_stmt ////////////
+mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n"
+multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT
+mixins: operand_name ("," ("\n" mixins | operand_name))*
+```
+
+Here is a simple example:
+
+```python
+schema Person:
+ mixin [FullNameMixin]
+ firstName: str = "default"
+ lastName: str
+
+schema FullNameMixin:
+ fullName: str = "{} {}".format(firstName, lastName)
+
+JohnDoe = Person {
+ firstName = "John"
+ lastName = "Doe"
+}
+```
+
+The result is a **dict**:
+
+```python
+{
+ 'JohnDoe': {
+ 'firstName': 'John'
+ 'lastName': 'Doe'
+ 'fullName': 'John Doe'
+ }
+}
+```
+
+Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected.
+
+Notes:
+
+- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported.
+- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported.
+
+### Protocol
+
+In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows:
+
+- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used.
+- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas.
+
+We can use **protocol** to add an optional host type to the dynamically inserted **mixin**.
+
+The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type.
+
+```python
+protocol DataProtocol: # A mixin host type
+ data: str
+
+mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type
+ x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol`
+```
+
+In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`:
+
+```python
+protocol DataProtocol:
+ data: str
+
+mixin DataMixin for DataProtocol:
+ x: int = data # Error: expect int, got str
+ x: str = data # Error: can't change schema field type of 'x' from int to str
+```
+
+Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported.
+
+```python
+protocol DataProtocol:
+ data: str
+
+schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol
+ x: str = data
+```
+
+### Schema Context Evaluation
+
+The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows:
+
+```
+|------------------------------------------|
+| attribute defaulting |
+|------------------------------------------|
+| configuration union |
+|------------------------------------------|
+| attribute templating |
+|------------------------------------------|
+| statements in declaration order |
+|------------------------------------------|
+| mixins in declaration order |
+|------------------------------------------|
+| check expressions in any order |
+|------------------------------------------|
+```
+
+In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once.
+Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as:
+
+```
+|-----------------|
+| schema a |
+|-----------------|
+| schema b |
+|-----------------|
+| schema c |
+|-----------------|
+```
+
+### Members
+
+Built-in function and members of schema
+
+- instances(full_pkg: bool = False)
+ Return the list of existing instances of a schema in the main package. When the `full_pkg` is set `True`, return all schema instances in the whole program.
+
+### Irrelevant Order Calculation
+
+The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference.
+
+Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation.
+
+Please note that there can be no circular references between different schema attribute values.
+
+We can see this feature through the following examples.
+
+```python
+schema Person:
+ name?: str
+ age: int = _age
+
+ _age = 10
+
+ if name == "Son":
+ _age = 18
+
+schema Son(Person):
+ name: str = "Son"
+
+person = Person {}
+son = Son {}
+```
+
+The output is
+
+```yaml
+person:
+ name: null
+ age: 10
+son:
+ name: Son
+ age: 18
+```
+
+Besides, we can achieve KCL polymorphism such as
+
+```python
+schema Person:
+ name?: str
+ _age: int = _age
+
+ _age = 10
+ if name == "Son":
+ _age = 18
+ elif name == "SonConf":
+ _age = 24
+
+schema Son(Person):
+ name: str = "Son"
+
+person = Person() {}
+son = Son() {
+ name = "SonConf"
+}
+```
+
+The output is
+
+```yaml
+person:
+ name: null
+ age: 10
+son:
+ name: SonConf
+ age: 24
+```
+
+More examples:
+
+```python
+schema Fib:
+ n1: int = n - 1
+ n2: int = n1 - 1
+ n: int
+ value: int = _value
+
+ if n <= 2:
+ _value = 1
+ else:
+ _value = (Fib {n = n1}).value + (Fib {n = n2}).value
+
+fib8 = (Fib {n = 8}).value
+```
+
+The output is
+
+```yaml
+fib8: 21
+```
+
+As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/statements.md
new file mode 100644
index 000000000..179410b54
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/statements.md
@@ -0,0 +1,185 @@
+---
+title: "Statements"
+linkTitle: "Statements"
+type: "docs"
+weight: 2
+description: Statements
+---
+
+## Syntax
+
+In KCL, statements consist of small statements and compound statements. The syntax is the following:
+
+```bnf
+preamble_statement: preamble_small_stmt | preamble_compound_stmt
+preamble_small_stmt: (small_stmt | import_stmt) NEWLINE
+preamble_compound_stmt: compound_stmt | schema_stmt
+statement: small_stmt NEWLINE | compound_stmt
+compound_stmt: if_stmt
+small_stmt: assign_stmt | expr_stmt | assert_stmt
+```
+
+The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement.
+
+### Small Statements
+
+A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed.
+
+#### Assignment Statements
+
+Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following:
+
+```bnf
+assign_stmt: target_primary (":" type) ("=" target_primary)* "=" test | target_primary aug_assign test
+aug_assign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>="
+target_primary: identifier | target_primary DOT identifier
+```
+
+An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side.
+
+The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots.
+
+Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative.
+
+Examples:
+
+```python
+k = 1
+a.b = "a.b"
+```
+
+To keep it simple, the compound target is not supported as **target_primary**.
+
+The right value of an assignment statement is a conditional expression, which is discussed separately.
+
+An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`.
+
+The **target_primary** on the left-hand side is the same as assignment statement. Examples:
+
+```python
+_x -= 1
+_filename += ".k"
+```
+
+There is no concept of in-place modification in KCL. The `aug_assign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**.
+
+In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows:
+
+- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**.
+
+See **expressions** spec for more details of union operator in **Arithmetic Operations**.
+
+#### Expression Statements
+
+An expression statement evaluates an expression and discards its result.
+
+Syntax:
+
+```bnf
+expr_stmt: expression
+```
+
+An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec.
+
+```python
+print(k) # print a variable
+```
+
+#### Import Statements
+
+Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs.
+
+Syntax:
+
+```bnf
+import_stmt: "import" dot_name ("as" NAME)?
+dot_name: [leading_dots] identifier (DOT identifier)*
+leading_dots: "."+
+```
+
+Examples:
+
+```python
+import math # import a built-in module math
+import pkg # import pkg
+import pkg.foo # import pkg.foo
+import pkg.subpkg # import a subpkg in a pkg
+import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg
+import ...pkg2 # Go two levels up then import pkg2
+```
+
+See **module** spec for more details of module spec.
+
+#### Assert Statements
+
+Assert statements are a convenient way to insert debugging assertions into KCL code.
+
+The syntax is the following:
+
+```
+assert_stmt: ASSERT test ("if" test)? ("," test)?
+```
+
+The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`.
+
+Examples:
+
+```python
+assert: x > 1 # report an error on x <= 1
+```
+
+#### Conditional Statements
+
+KCL allows using conditional statements to control the instructions to
+be executed. They are also called the control-flow statements.
+
+The only type of control-flow syntax is the well-known `if-elif-else` syntax.
+
+The syntax of the `if-elif-else` statement is the following.
+
+```bnf
+if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)?
+suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT
+```
+
+An `if` or `elif` statement evaluates a given expression. When the expression
+is evaluated to `True`, a list of statements following `:` are executed.
+
+The following is an example:
+
+```python
+a = 10
+if a == 0:
+ print("a is zero")
+elif a < 100:
+ print("a < 100")
+ print("maybe a is negative")
+else:
+ print("a >= 100")
+```
+
+`if-elif-else` statements can be nested. For example:
+
+```python
+a = 10
+if a == 0:
+ print("a is zero")
+elif a < 100:
+ print("a < 100")
+ if a < 0:
+ print("a is negative")
+ print("No matter a is negative or positive, this message is printed")
+else:
+ print("a >= 100")
+```
+
+#### Schema Statements
+
+Schema statements are used to define a type of configuration data. The syntax is the following:
+
+```bnf
+schema_stmt: [decorators] "schema" identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body]
+schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT
+```
+
+See **schema** spec for more details of schema spec.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/variables.md
new file mode 100644
index 000000000..b3e1c539a
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/spec/variables.md
@@ -0,0 +1,68 @@
+---
+title: "Variables"
+linkTitle: "Variable"
+type: "docs"
+weight: 2
+description: Variable
+---
+
+In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`.
+
+```python
+spam = "ham"
+```
+
+There are two types of variables, which are global variables and list comprehension local variables.
+
+- A global variable is defined not within any context.
+- A comprehension local variable is defined inside a comprehension.
+
+A variable can be used after definition, until the end of the current scope.
+
+For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files.
+
+For a list comprehension local variable, the scope is the list comprehension it is defined in.
+
+More information on modules, list comprehensions and scopes will be discussed in later chapters.
+
+## Immutability
+
+Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified).
+
+The following code is illegal, and KCL will report an error during evaluation.
+
+```python
+spam = "ham"
+spam = "eggs" # Error: The immutability rule is violated!
+```
+
+- A variable starts with the `_` character is mutable.
+
+```python
+_spam
+cond = True
+if cond:
+ _spam = "ham"
+else:
+ _spam = "eggs"
+```
+
+## Variable Exporting
+
+As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format.
+
+The rules are the followings:
+
+- Living global variables at the end of an evaluation will be dumped out.
+- If the name of a variable starts with the `_` character, it will not be dumped out.
+
+## Uniqueness of Exported Variable Identifier
+
+Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package.
+
+Two variable identifiers are different if:
+
+- they are spelled differently
+- they are defined in different packages and are not compiled in a single execution
+
+Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/tour.md
new file mode 100644
index 000000000..c724d2bc3
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/tour.md
@@ -0,0 +1,3281 @@
+---
+title: "KCL 之旅"
+sidebar_position: 1
+---
+
+本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。
+
+### 重要概念
+
+在学习 KCL 语言时,请牢记以下事实和概念:
+
+- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。
+- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。
+- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。
+- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。
+- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。
+- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。
+- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。
+- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。
+- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。
+- 支持**内置函数**和**插件**以简化编写。
+
+### 关键字
+
+下表列出了 KCL 语言的关键字。
+
+```txt
+True False None Undefined import
+and or in is not
+as if else elif for
+schema mixin protocol check assert
+all any map filter lambda
+rule
+```
+
+### 标识符
+
+在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。
+
+- 标识符由字母、数字、下划线或前缀 `$` 组成。
+- 标识符不能与关键字重复,除非它们有 `$` 前缀。
+- 标识符不得包含任何嵌入的空格或符号。
+- 可以在标识符中的任何位置使用字母和下划线。
+- 数字不能放在标识符的第一位。
+- `$` 字符只能放在标识符的第一个位置。
+
+示例:
+
+```python
+x
+a
+b1
+b_2
+_c
+$if
+```
+
+为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`:
+
+示例:
+
+```python
+pkg.a
+```
+
+在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。
+
+#### 标识符前缀
+
+使用 `$` 前缀符号定义关键字标识符。
+
+```python
+$if = 1
+$else = "s"
+```
+
+请注意,非关键字标识符是否有 `$` 符号都是同样的效果。
+
+```python
+_a = 1
+$_a = 2 # equal to `_a = 2`
+```
+
+### 变量
+
+以下是如何创建并实例化变量的例子:
+
+```python
+name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo"
+```
+
+它对应了如下 YAML 输出:
+
+```yaml
+name: Foo
+```
+
+在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。
+
+```python
+name = "Foo" # exported
+
+...
+
+name = "Bar" # error: a exported declaration variable can only be set once.
+```
+
+作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。
+
+```python
+_name = "Foo" # _ variables are not output to YAML and are mutable
+_name = "Bar"
+```
+
+请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。
+
+```python
+False = 1 # Error
+True = False # Error
+None = Undefined # Error
+Undefined = None # Error
+```
+
+### 内置类型
+
+KCL 支持以下类型:
+
+- 数字
+- 字符串
+- 布尔
+- 列表
+- 字典
+
+#### 数字
+
+KCL 的数字类型有两种形式:
+
+- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807.
+- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。
+
+整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。
+
+整数是不带小数点的数字。以下是一些定义整数的例子:
+
+```python
+a = 1
+b = -1
+c = 0x10 # hexadecimal literal
+d = 0o10 # octal literal
+e = 010 # octal literal
+f = 0b10 # binary literal
+g = int("10") # int constructor
+```
+
+如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例:
+
+```python
+a = 1.10
+b = 1.0
+c = -35.59
+d = 32.3e+18
+f = -90.
+h = 70.2E-12
+i = float("112") # float constructor
+```
+
+内置数学库可用于数字类型:
+
+```python
+import math
+
+assert abs(-40) == 40
+assert round(70.23456) == 70
+assert min(80, 100, 1000) == 80
+assert max(80, 100, 1000) == 1000
+assert sum([0,1,2]) == 3
+assert math.ceil(100.12) == 101.0
+assert math.floor(100.12) == 100.0
+assert math.pow(100, 2) == 10000.0
+```
+
+KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。
+
+```bash
+kcl main.k -r -d
+```
+
+请注意,为了性能考虑该功能只能在 `debug` 模式中使用。
+
+##### 单位字面值
+
+在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。
+
+- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`
+- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`
+
+```python
+# SI
+n = 1n # 1e-09
+u = 1u # 1e-06
+m = 1m # 1e-03
+k = 1k # 1000
+K = 1K # 1000
+M = 1M # 1000000
+G = 1G # 1000000000
+T = 1T # 100000000000
+P = 1P # 1000000000000000
+# IEC
+Ki = 1Ki # 1024
+Mi = 1Mi # 1024 ** 2
+Gi = 1Gi # 1024 ** 3
+Ti = 1Ti # 1024 ** 4
+Pi = 1Pi # 1024 ** 5
+```
+
+此外,我们还可以使用定义在 `units` 模块中的单位常量:
+
+```python
+import units
+
+n = 1 * units.n # 1e-09
+u = 1 * units.u # 1e-06
+m = 1 * units.m # 1e-03
+k = 1 * units.k # 1000
+K = 1 * units.K # 1000
+M = 1 * units.M # 1000000
+G = 1 * units.G # 1000000000
+T = 1 * units.T # 1000000000000
+P = 1 * units.P # 1000000000000000
+# IEC
+Ki = 1 * units.Ki # 1024
+Mi = 1 * units.Mi # 1024 ** 2
+Gi = 1 * units.Gi # 1024 ** 3
+Ti = 1 * units.Ti # 1024 ** 4
+Pi = 1 * units.Pi # 1024 ** 5
+```
+
+我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数
+
+```python
+import units
+# SI
+K = units.to_K(1000) # "1K"
+M = units.to_M(1000000) # "1M"
+G = units.to_G(1000000000) # "1G"
+T = units.to_T(1000000000000) # "1T"
+P = units.to_P(1000000000000000) # "1P"
+# IEC
+Ki = units.to_Ki(1024) # "1Ki"
+Mi = units.to_Mi(1024 ** 2) # "1Mi"
+Gi = units.to_Gi(1024 ** 3) # "1Gi"
+Ti = units.to_Ti(1024 ** 4) # "1Ti"
+Pi = units.to_Pi(1024 ** 5) # "1Pi"
+```
+
+```python
+import units
+# SI
+K = units.to_K(int("1M")) # "1000K"
+M = units.to_M(int("1G")) # "1000M"
+G = units.to_G(int("1T")) # "1000G"
+T = units.to_T(int("1P")) # "1000T"
+P = units.to_P(int("10P")) # "10P"
+# IEC
+Ki = units.to_Ki(int("1Mi")) # "1024Ki"
+Mi = units.to_Mi(int("1Gi")) # "1024Mi"
+Gi = units.to_Gi(int("1Ti")) # "1024Gi"
+Ti = units.to_Ti(int("1Pi")) # "1024Ti"
+Pi = units.to_Pi(int("10Pi")) # "10Pi"
+```
+
+单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。
+
+```python
+import units
+
+type NumberMultiplier = units.NumberMultiplier
+
+x0: NumberMultiplier = 1M # Ok
+x1: NumberMultiplier = x0 # Ok
+x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)'
+```
+
+我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。
+
+```python
+a: int = int(1Ki) # 1024
+b: float = float(1Ki) # 1024.0
+c: str = str(1Mi) # "1Mi"
+```
+
+#### 字符串
+
+字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串:
+
+```python
+'allows embedded "double" quotes' # Single quotes
+"allows embedded 'single' quotes" # Double quotes
+'''Three single quotes''', """Three double quotes""" # Triple quoted
+```
+
+三引号用于定义多行字符串。
+
+```python
+"""This is a long triple quoted string
+may span multiple lines.
+"""
+```
+
+请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。
+
+```python
+'This is my book named "foo"' # don't need to escape double quotes in single quoted strings.
+"This is my book named 'foo'" # don't need to escape single quotes in double quoted strings.
+```
+
+我们可以使用 `+` 操作符连接字符串:
+
+```python
+x = 'The + operator ' + 'works, as well.'
+```
+
+我们可以使用 `str` 内置函数将 int 或 float 转为字符串:
+
+```python
+x = str(3.5) # "3.5"
+```
+
+可以使用很多内置的字符串函数:
+
+```python
+x = "length"
+assert len(x) == 6 # True
+assert x.capitalize() == "Length"
+assert x.count("gt") == 1
+assert x.endswith("th") == True
+assert x.find("gth") == 3
+assert "{} {}".format("hello", "world") == 'hello world'
+assert x.index("gth") == 3
+assert x.isalnum() == True
+assert x.isalpha() == True
+assert "123456".isdigit() == True
+assert x.islower() == True
+assert " ".isspace() == True
+assert "This Is Title Example".istitle() == True
+assert x.isupper() == False
+assert "|".join(["a", "b", "c"]) == "a|b|c"
+assert "LENGTH".lower() == "length"
+assert ' spacious '.lstrip() == 'spacious '
+assert x.replace("th", "ht") == "lenght"
+assert "lengthlength".rfind("le") == 6
+assert "lengthlength".rindex("le") == 6
+assert "length length".rsplit() == ["length", "length"]
+assert "length ".rstrip() == "length"
+assert "length length".split() == ["length", "length"]
+assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl']
+assert "length".startswith('len') == True
+assert "***length***".strip('*') == "length"
+assert "length length".title() == "Length Length"
+assert x.upper() == "LENGTH"
+```
+
+格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。
+
+此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。
+
+注意,如果不想 `${...}` 表示字符串插值 ,我们可以在 `$` 之前添加`\` 字符表示直接以字符串的形式输出 `${...}`。
+
+```python
+world = "world"
+a = "hello {}".format(world) # "hello world"
+b = "hello ${world}" # "hello world"
+c1 = "$hello ${world}$" # "$hello world$"
+c2 = "$" + "hello ${world}" + "$" # "$hello world$"
+c3 = "$" + "hello \${world}" + "$" # "$hello ${world}$"
+
+myDict = {
+ "key1" = "value1"
+ "key2" = "value2"
+}
+myList = [1, 2, 3]
+
+d = "here is myDict in json: ${myDict: #json}"
+# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}'
+
+e = "here is myDict in yaml:\n${myDict: #yaml}"
+# e: |
+# here is myDict in yaml:
+# key1: value1
+# key2: value2
+
+f = "here is myList in json: ${myList: #json}"
+# f: 'here is myList in json: [1, 2, 3]'
+g = "here is myList in yaml: ${myList: #yaml}"
+# g: |
+# here is myList in yaml: - 1
+# - 2
+# - 3
+```
+
+此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。
+
+- `|` 表示 **块文字样式**,指示块内换行符的行为方式。
+- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。
+- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。
+
+例如,**strip 块文字样式** yaml 字符串是
+
+```yaml
+example: |-
+ Several lines of text,
+ with some "quotes" of various 'types',
+ and also a blank line:
+
+ plus another line at the end.
+```
+
+结果为:
+
+```plain
+Several lines of text,
+with some "quotes" of various 'types',
+and also a blank line:
+
+plus another line at the end.
+```
+
+更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。
+
+##### 原始字符串
+
+KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。
+
+- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下:
+
+```python
+s = "Hi\nHello"
+raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix.
+```
+
+```yaml
+s: |-
+ Hi
+ Hello
+raw_s: Hi\nHello
+```
+
+- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下:
+
+```python
+worldString = "world"
+s = "Hello ${worldString}"
+raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix.
+```
+
+```yaml
+worldString: world
+s: Hello world
+raw_s: Hello ${worldString}
+```
+
+此外,原始字符串最常用的场景是在正则表达式中使用:
+
+```python
+import regex
+
+key = "key"
+result = regex.match(key, r"[A-Za-z0-9_.-]*") # True
+```
+
+#### 布尔值
+
+布尔值有两个常量对象:`False` 和 `True`.
+
+```python
+a = True
+b = False
+```
+
+#### List
+
+List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子:
+
+```python
+list = [1, 2, 3]
+assert len(list) == 3 # True
+assert list[0] == 1 # True
+```
+
+我们可以使用列表推导式构建列表:
+
+```python
+list = [ _x for _x in range(20) if _x % 2 == 0]
+assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True
+```
+
+并且还可以使用嵌套的列表推导式:
+
+```python
+matrix = [[1, 2], [3,4], [5,6], [7,8]]
+transpose = [[row[_i] for row in matrix] for _i in range(2)]
+assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True
+```
+
+此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。
+
+```python
+data = [1000, 2000, 3000]
+# Single variable loop
+dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000]
+dataLoop2 = [i for i in data if i == 2000] # [2000]
+dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000]
+# Double variable loop
+dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002]
+dataLoop5 = [v for i, v in data if v == 2000] # [2000]
+# Use `_` to ignore loop variables
+dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000]
+dataLoop7 = [i for i, _ in data] # [0, 1, 2]
+dataLoop8 = [v for _, v in data if v == 2000] # [2000]
+```
+
+我们可以通过 `+` 连接列表:
+
+```python
+_list0 = [1, 2, 3]
+_list1 = [4, 5, 6]
+joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6]
+```
+
+我们可以使用解包操作符 `*` 合并多个列表:
+
+```python
+_list0 = [1, 2, 3]
+_list1 = [4, 5, 6]
+union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6]
+```
+
+我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。
+
+```python
+a = 1 # 1
+data = [
+ 1
+ if a == 1: 2
+ if a > 0: 3
+ if a < 0: 4
+] # [1, 2, 3]
+```
+
+```python
+a = 1 # 1
+data1 = [
+ 1
+ if a == 1:
+ 2
+ elif a == 2:
+ 3
+ else:
+ 3
+] # [1, 2]
+data2 = [
+ 1
+ if a == 1: 2
+ elif a == 2: 2
+ else: 3
+] # [1, 2]
+```
+
+我们可以合并(union)列表:
+
+```python
+_list0 = [1, 2, 3]
+_list1 = [4, 5, 6]
+union_list = _list0 | _list1 # [4, 5, 6]
+```
+
+我们可以使用 `for k in list_var` 表达式遍历列表:
+
+```python
+data = [1, 2, 3]
+dataAnother = [val * 2 for val in data] # [2, 4, 6]
+```
+
+#### Dict
+
+Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序:
+
+这里有几个简单的 KCL 字典:
+
+```python
+a = {"one" = 1, "two" = 2, "three" = 3}
+b = {'one' = 1, 'two' = 2, 'three' = 3}
+assert a == b # True
+assert len(a) == 3 # True
+```
+
+在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`:
+
+```python
+data = {
+ "key1" = "value1" # Ignore the comma ',' at the end of line
+ "key2" = "value2"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+在 Dict 键上使用简单的字面值时可以省略引号:
+
+```python
+data = {
+ key1 = "value1" # Ignore key quotation '"'
+ key2 = "value2"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+请注意,当属性中存在 `-` 和 `.` 等其他连字符时,我们必须使用引号。
+
+```python
+data = {
+ "config.dot.attr" = "value1" # Note we use `"config.dot.attr"` instead of `config.dot.attr` here.
+ "config-hyphen-attr" = "value2" # Note we use `"config-hyphen-attr"` instead of `config-hyphen-attr` here.
+}
+```
+
+此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。
+
+```python
+person = {
+ base.count = 2
+ base.value = "value"
+ labels.key = "value"
+} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}}
+```
+
+输出 YAML 为:
+
+```yaml
+person:
+ base:
+ count: 2
+ value: value
+ labels:
+ key: value
+```
+
+在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子
+
+```python
+config = {
+ name = "me"
+ metadata.name = name # Reference `name` with the value `"me"` in `config` directly.
+}
+```
+
+输出 YAML 为:
+
+```yaml
+config:
+ name: me
+ metadata:
+ name: me
+```
+
+我们可以使用字典推导式构建字典:
+
+```python
+x = {str(i): 2 * i for i in range(3)}
+assert x == {"0" = 0, "1" = 2, "2" = 4}
+```
+
+此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。
+
+```python
+data = {key1 = "value1", key2 = "value2"}
+# Single variable loop
+dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"}
+dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"}
+# Double variable loop
+dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"}
+dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"}
+dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"}
+# Use `_` to ignore loop variables
+dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"}
+dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"}
+```
+
+我们可以使用解包操作符 `**` 来合并字典:
+
+```python
+_part1 = {
+ a = "b"
+}
+
+_part2 = {
+ c = "d"
+}
+
+a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"}
+```
+
+此外,union 操作符 `|` 也能达到同样的效果:
+
+```python
+_part1 = {
+ a = "b"
+}
+
+_part2 = {
+ c = "d"
+}
+
+a_dict = _part1 | _part2 # {"a: "b", "c": "d"}
+```
+
+我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。
+
+```python
+a = 1 # 1
+data = {
+ key1 = "value1"
+ if a == 1: key2 = "value2"
+ if a > 0: key3 = "value3"
+ if a < 0: key4 = "value4"
+} # {"key1": "value1", "key2": "value2", "key3": "value3"}
+```
+
+```python
+a = 1 # 1
+data1 = {
+ key1 = "value1"
+ if a == 1:
+ key2 = "value2"
+ elif a > 0:
+ key3 = "value3"
+ else:
+ key4 = "value4"
+} # {"key1": "value1", "key2": "value2"}
+data2 = {
+ key1 = "value1"
+ if a == 1: key2 = "value2"
+ elif a > 0: key3 = "value3"
+ else: key4 = "value4"
+} # {"key1": "value1", "key2": "value2"}
+```
+
+我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。
+
+```python
+data = {key1 = "value1", key2 = "value2"}
+dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"}
+containsKey1 = "key1" in data # True
+containsKey2 = "key" in data # False
+```
+
+#### None
+
+在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。
+
+```python
+a = None
+b = [1, 2, None]
+c = {key1 = "value1", key2 = None}
+```
+
+输出如下:
+
+```yaml
+a: null
+b:
+ - 1
+ - 2
+ - null
+c:
+ key1: value1
+ key2: null
+```
+
+请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。
+
+```python
+a = 1 + None # error
+b = int(None) # error
+c = not None # True
+d = None == None # True
+e = None or 1 # 1
+f = str(None) # None
+```
+
+#### Undefined
+
+`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。
+
+```python
+a = Undefined
+b = [1, 2, Undefined]
+c = {key1 = "value1", key2 = Undefined}
+```
+
+输出如下:
+
+```yaml
+b:
+ - 1
+ - 2
+c:
+ key1: value1
+```
+
+请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。
+
+```python
+a = 1 + Undefined # error
+b = int(Undefined) # error
+c = not Undefined # True
+d = Undefined == Undefined # True
+e = Undefined or 1 # 1
+f = str(Undefined) # Undefined
+```
+
+### 运算符
+
+以下字符表示运算符:
+
+```python
++ - * ** / // %
+<< >> & | ^ < >
+~ <= >= == != @ \
+```
+
+#### 算数运算符
+
+KCL 支持常见的算数运算符:
+
+```python
+assert 2 + 3 == 5
+assert 2 - 3 == -1
+assert 2 * 3 == 6
+assert 5 / 2 == 2.5
+assert 5 // 2 == 2
+assert 5 % 2 == 1
+```
+
+#### 相等和关系运算符
+
+KCL 支持相等和关系运算符:
+
+```python
+assert 2 == 2
+assert 2 != 3
+assert 3 > 2
+assert 2 < 3
+assert 3 >= 3
+assert 2 <= 3
+```
+
+#### 逻辑运算符
+
+我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`:
+
+```python
+if not done and (col == 0 or col == 3):
+ # ...Do something...
+
+```
+
+#### 位运算符和移位运算符
+
+以下是位运算符和移位运算符的例子:
+
+```python
+value = 0x22
+bitmask = 0x0f
+
+assert (value & bitmask) == 0x02
+assert (value & ~bitmask) == 0x20
+assert (value | bitmask) == 0x2f
+assert (value ^ bitmask) == 0x2d
+assert (value << 4) == 0x220
+assert (value >> 4) == 0x02
+```
+
+`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。
+
+位运算示例:
+
+```python
+0x12345678 | 0xFF # 0x123456FF
+```
+
+联合基本类型示例:
+
+```python
+schema x:
+ a: int | str # attribute a could be a int or string
+```
+
+#### 赋值运算符
+
+以下 token 作为语法中的分隔符:
+
+```txt
+ ( ) [ ] { }
+ , : . ; = ->
+ += -= *= /= //= %=
+ &= ^= >>= <<= **=
+```
+
+以下是使用赋值和参数赋值赋值运算符的例子:
+
+```python
+_a = 2
+_a *= 3
+_a += 1
+assert _a == 7
+```
+
+#### Identity 运算符
+
+以下关键字作为语法中的 identity 运算符:
+
+```python
+is, is not
+```
+
+Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子:
+
+```python
+empty_String = ""
+empty_String is not None # True
+```
+
+#### 成员运算符
+
+以下关键字作为语法中的成员运算符:
+
+```python
+in, not in
+```
+
+- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。
+- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。
+
+成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。
+
+```python
+1 in [1, 2, 3] # True
+
+d = {one = 1, two = 2}
+"one" in d # True
+"three" in d # False
+1 in d # False
+[] in d # False
+
+"nasty" in "dynasty" # True
+"a" in "banana" # True
+"f" not in "way" # True
+
+d = Data {one = 1, two = 2} # Data is a schema with attributes one and two
+"one" in d # True
+"three" in d # False
+```
+
+#### 推导式
+
+一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。
+
+我们可以如下使用列表和字典的推导表达式:
+
+```python
+listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension
+dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension
+```
+
+#### 其他运算符
+
+- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。
+- 使用 **[]** 引用列表中指定索引处的值。
+- 使用 **:** 定义类型注解。
+- 使用 **.** 引用成员字段。
+- 使用 **\\** 续行符编写长表达式。
+
+```python
+longString = "Too long expression " + \
+ "Too long expression " + \
+ "Too long expression "
+```
+
+### 表达式
+
+#### 条件表达式
+
+条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。
+
+示例:
+
+```python
+x = True if enabled else False # If enabled is True, x is True, otherwise x is False
+```
+
+#### 索引表达式
+
+索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。
+
+有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。
+
+```python
+val = "abc"
+list = ["zero", "one", "two"]
+str_0 = val[0] # "a"
+str_1 = val[1] # "b"
+str_n1 = val[-1] # "c"
+
+list_0 = list[0] # "zero"
+list_1 = list[1] # "one"
+list_n1 = list[-1] # "two"
+```
+
+索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined`
+
+出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。
+
+```python
+d = {key1 = "value1", key2 = "value2"}
+key1value = d["key1"] # value1
+key2value = d["key2"] # value2
+```
+
+尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。
+
+#### 切片表达式
+
+切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。
+
+`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。
+
+从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。
+
+如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。
+
+```python
+val = "abc"
+len = len(val)
+a = val[1:len] # "bc" (remove first element)
+b = val[0:-1] # "ab" (remove last element)
+c = val[1:-1] # "b" (remove first and last element)
+```
+
+```python
+"abc"[1:] # "bc" (remove first element)
+"abc"[:-1] # "ab" (remove last element)
+"abc"[1:-1] # "b" (remove first and last element)
+"banana"[1::2] # "aaa" (select alternate elements starting at index 1)
+"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4)
+```
+
+KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。
+
+#### 函数调用
+
+KCL 允许调用内置函数,或者调用内置和系统模块中的函数。
+
+调用函数的基本方法如下所示:
+
+```python
+import math
+
+a = math.pow(2, 3) # 2 powers 3 is 8.
+b = len([1, 2, 3]) # the length of [1, 2, 3] is 3
+```
+
+参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。
+
+```python
+print("hello world", end="")
+```
+
+请注意:
+
+- 有些函数参数具有默认值。
+- 一些函数接受可变参数。
+
+如果没有为没有默认值的参数提供参数,则会抛出错误。
+
+#### 选择表达式
+
+选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法:
+
+`x.y`
+
+- dict: 表示字典 `x` 中键 `y` 对应的值。
+- schema: 表示 schema `x` 中 `y` 属性的值。
+- package: 表示 package `x` 中 `y` 标示的标识符。
+
+示例:
+
+```python
+schema Person:
+ name: str
+ age: int
+
+person = Person {
+ name = "Alice"
+ age = 18
+}
+name = person.name # "Alice"
+age = person.age # 18
+
+myDict = {
+ key = "value"
+}
+result = myDict.key # "value"
+```
+
+`x?.y`
+
+`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。
+
+```python
+# Example of dict:
+data = {"key" = "value"}
+a = data?.key # "value"
+b = data?.name # Undefined
+
+# example of schema instance:
+schema Company:
+ name: str
+ address: str
+
+schema Person:
+ name: str
+ job?: Company
+
+alice = Person {
+ name = "alice"
+}
+
+if alice?.job?.name == "Group":
+ print("work in Group")
+```
+
+#### Quantifier 表达式
+
+Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式:
+
+- **all**
+ - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。
+ - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。
+ - 如果集合为空,返回 true。
+ - 支持表达式执行期间逻辑表达式的短路。
+- **any**
+ - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。
+ - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。
+ - 如果集合为空,返回 false。
+ - 支持表达式执行期间逻辑表达式的短路。
+- **map**
+ - 映射集合中的元素生成新的列表。
+ - 新列表的长度严格等于原列表的长度。
+- **filter**
+ - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。
+ - 当表达式为 true 时才将元素添加到子集合。
+ - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。
+
+**all** 和 **any** 表达式的示例代码:
+
+```python
+schema Config:
+ volumes: [{str:}]
+ services: [{str:}]
+
+ check:
+ all service in services {
+ service.clusterIP == "NONE" if service.type == "ClusterIP"
+ }, "invalid cluster ip"
+
+ any volume in volumes {
+ volume.mountPath in ["/home/admin", "/home/myapp"]
+ }
+```
+
+**map** 和 **filter** 表达式的示例代码:
+
+```python
+a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] {
+ {name = e.name, value = int(e.value) ** 2}
+} # [{"name": "1", value: 1}, {"name": "2", "value": 4}]
+
+b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"]
+
+c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] {
+ int(e.value) > 1
+} # [{"name": "2", "value": 2}]
+
+d = filter _, v in {a = "foo", b = "bar"} {
+ v == "foo"
+} # {"a": "foo"}
+```
+
+请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。
+
+### 流程控制表达式
+
+#### If 和 Else
+
+KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下:
+
+```python
+a = 10
+if a == 0:
+ print("a is zero")
+elif a < 100:
+ print("a < 100")
+ print("maybe a is negative")
+else:
+ print("a >= 100")
+```
+
+`elif` 的例子:
+
+```python
+_result = 0
+if condition == "one":
+ _result = 1
+elif condition == "two":
+ _result = 2
+elif condition == "three":
+ _result = 3
+else:
+ _result = 4
+```
+
+`if-elif-else` 表达式可以嵌套,示例如下:
+
+```python
+a = 10
+if a == 0:
+ print("a is zero")
+elif a < 100:
+ print("a < 100")
+ if a < 0:
+ print("a is negative")
+ print("No matter a is negative or positive, this message is printed")
+else:
+ print("a >= 100")
+```
+
+此外,对于简单的 `if` 表达式如下:
+
+```python
+if success:
+ _result = "success"
+else:
+ _result = "failed"
+```
+
+我们可以使用 ` if else ` 的形式将它们写在一行:
+
+```python
+_result = "success" if success else "failed"
+```
+
+`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。
+
+请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。
+
+```python
+_emptyStr = ""
+_emptyList = []
+_emptyDict = {}
+isEmptyStr = False if _emptyStr else True
+isEmptyList = False if _emptyList else True
+isEmptyDict = False if _emptyDict else True
+```
+
+结果为:
+
+```yaml
+isEmptyStr: true
+isEmptyList: true
+isEmptyDict: true
+```
+
+### 断言语句
+
+当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下:
+
+```python
+a = 1
+b = 3
+# a != b evaluates to True, therefore no error should happen.
+assert a != b
+# a == b is False, in the reported error message, the message "SOS" should be printed.
+assert a == b, "SOS"
+```
+
+此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言
+
+- 使用 if 语句书写条件断言
+
+```python
+a = None
+if a:
+ assert a > 2:
+```
+
+- 使用 if 表达式书写条件断言
+
+```python
+a = None
+assert a > 2 if a
+```
+
+### 函数
+
+KCL 支持使用 lambda 关键字定义一个函数
+
+```python
+func = lambda x: int, y: int -> int {
+ x + y
+}
+a = func(1, 1) # 2
+```
+
+lambda 函数具有如下特性:
+
+- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None
+- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型
+- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的
+
+```python
+_func = lambda x: int, y: int -> int {
+ x + y
+} # Define a function using the lambda expression
+_func = lambda x: int, y: int -> int {
+ x - y
+} # Ok
+_func = lambda x: int, y: int -> str {
+ str(x + y)
+} # Error (int, int) -> str can't be assigned to (int, int) -> int
+```
+
+lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。
+
+```python
+func = lambda x: int, y: int -> int {
+ x + y
+}
+x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)'
+```
+
+lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递
+
+```python
+a = 1
+func = lambda x: int {
+ x + a
+}
+funcOther = lambda f, para: int {
+ f(para)
+}
+r0 = funcOther(func, 1) # 2
+r1 = funcOther(lambda x: int {
+ x + a
+}, 1) # 2
+```
+
+输出为:
+
+```yaml
+a: 1
+r: 2
+```
+
+此外,可以定义一个匿名函数并直接调用。
+
+```python
+result = (lambda x, y {
+ z = 2 * x
+ z + y
+})(1, 1) # 3
+```
+
+并且还可以在 for 循环使用使用匿名函数
+
+```python
+result = [(lambda x, y {
+ x + y
+})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4]
+```
+
+请注意,KCL 中定义的函数的均为纯函数:
+
+- 函数的返回结果只依赖于它的参数。
+- 函数执行过程里面没有副作用。
+
+因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误:
+
+```python
+globalVar = 1
+func = lambda {
+ x = globalVar # Ok
+ globalVar = 1 # Error
+}
+```
+
+### 类型系统
+
+#### 类型注解
+
+类型注解可用于包级变量,schema 属性和参数。
+
+- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。
+- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。
+- 属性也可以是列表或字典:
+ - 未指定元素类型的列表为 `[]`。
+ - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。
+ - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。
+ - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。
+- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。
+ - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。
+- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。
+- 属性可以声明为任意类型,例如 `any`。
+
+示例
+
+- 基本类型
+
+```python
+"""Top level variable type annotation"""
+a: int = 1 # Declare a variable `a` that has the type `int` and the value `1`
+b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"`
+c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0`
+d: bool = True # Declare a variable `d` that has the type `bool` and the value `True`
+```
+
+- List/Dict/Schema 类型
+
+```python
+schema Person:
+ name: str = "Alice"
+ age: int = 10
+
+a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]`
+b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}`
+c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}`
+```
+
+- 联合类型
+
+```python
+# Basic union types
+schema x[argc: int]: # Schema argument type annotation
+ p: int | str # Schema attribute type annotation
+```
+
+```python
+# Literal union types
+schema LiteralType:
+ # String literal union types, x_01 can be one of "TCP" and "UDP"
+ x_01: "TCP" | "UDP"
+ # Number literal union types, x_02 can be one of 2, 4, and 6
+ x_02: 2 | 4 | 6
+ # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi
+ x_03: 1Gi | 2Gi | 4Gi
+
+x = LiteralType {
+ x_01 = "TCP"
+ x_02 = 2
+ x_03 = 1Gi
+}
+```
+
+当属性的值不符合联合类型定义时,编译器会抛出错误:
+
+```python
+# Literal union types
+schema LiteralType:
+ # String literal union types, x_01 can be one of "TCP" and "UDP"
+ x_01: "TCP" | "UDP"
+
+x = LiteralType {
+ x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP)
+}
+```
+
+- Any 类型
+
+```python
+# Any type
+schema Config:
+ literalConf: any = 1
+ dictConf: {str:any} = {key = "value"}
+ listConf: [any] = [1, "2", True]
+
+config = Config {}
+```
+
+请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。
+
+此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。
+
+```python
+_a = 1 # The type of `_a` is `int`
+_a = "s" # Error: expect int, got str(s)
+```
+
+变量可以赋值给其上界类型,但不能赋值给它的特化类型。
+
+`None` 和 `Undefined` 可以赋值给任何类型:
+
+- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。
+
+```python
+a: int = None
+b: str = Undefined
+c: any = 1
+d: any = "s"
+e: any = None
+```
+
+- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型.
+
+```python
+a: float = 1
+b: int = 1.0 # Error: expect int, got float(1.0)
+```
+
+- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型.
+
+```python
+a: int | str = 1
+b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s)
+```
+
+请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。
+
+#### 类型推导
+
+如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。
+
+- 整形数值被推断为 `int`。
+
+```python
+a = 1 # The variable `a` has the type `int`
+```
+
+- 浮点数被推断为 `float`。
+
+```python
+a = 1.0 # The variable `a` has the type `float`
+```
+
+- 字符串被推断为 `str`。
+
+```python
+a = "s" # The variable `a` has the type `str`
+```
+
+- 布尔值被推断为 `bool`。
+
+```python
+a = True # The variable `a` has the type `bool`
+b = False # The variable `b` has the type `bool`
+```
+
+- `None` 和 `Undefined` 被推断为 `any`。
+
+```python
+a = None # The variable `a` has the type `any`
+b = Undefined # The variable `b` has the type `any`
+```
+
+- 列表的类型根据元素类型推断,并且是可变大小的。
+
+```python
+a = [1, 2, 3] # The variable `a` has the type `[int]`
+b = [1, 2, True] # The variable `b` has the list union type `[int|bool]`
+c = ["s", 1] # The variable `c` has the list union type `[int|str]`
+```
+
+请注意,空列表将被推导为 `[any]` 类型。
+
+```python
+a = [] # The variable `a` has the type `[any]`
+```
+
+- 字典的类型是根据元素的键和值推断的,并且是可变大小的。
+
+```python
+a = {key = "value"} # The variable `a` has the type `{str:str}`
+b = {key = 1} # The variable `b` has the type `{str:int}`
+c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}`
+```
+
+请注意,空字典将被推导为 `{any:any}` 类型。
+
+```python
+a = {} # The variable `a` has the type `{any:any}`
+```
+
+- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。
+
+```python
+a: bool = True # The variable `a` has the type `bool`
+b = 1 if a else "s" # The variable `b` has the type `int|str`
+```
+
+当变量被推导为某个类型时,它的类型不能再改变。
+
+```python
+_a = 1
+_a = "s" # Error: expect int, got str(1)
+```
+
+#### 类型别名
+
+在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。
+
+```python
+type Int = int
+type String = str
+type StringOrInt = String | Int
+type IntList = [int]
+type StringAnyDict = {str:}
+```
+
+我们可以从一个包中导入一个类型并为它定义一个别名。
+
+```py
+import pkg
+
+type Data = pkg.Data
+```
+
+此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。
+
+```python
+# A type alias of string literal union types
+type Color = "Red" | "Yellow" | "Blue"
+
+schema Config:
+ color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"`
+
+config = Config {
+ color = "Blue"
+}
+```
+
+上述代码执行的输出结果为:
+
+```yaml
+config:
+ color: Blue
+```
+
+请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同
+
+```python
+type any = int | str # Error
+type int = str # Error
+type float = int # Error
+type bool = True # Error
+type str = "A" | "B" | "C" # Error
+```
+
+#### 类型守卫
+
+KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。
+
+```python
+import sub as pkg
+
+_a = 1
+
+t1 = typeof(_a)
+t2 = typeof("abc")
+
+schema Person:
+ name?: any
+
+_x1 = Person {}
+t3 = typeof(_x1)
+
+_x2 = pkg.Person {}
+t4 = typeof(_x2)
+t5 = typeof(_x2, full_name=True)
+
+t6 = typeof(_x1, full_name=True)
+
+# Output
+# t1: int
+# t2: str
+# t3: Person
+# t4: Person
+# t5: sub.Person
+# t6: __main__.Person
+```
+
+除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下:
+
+- 具有偏序关系的基础类型,比如 `float -> int`
+- 具有偏序关系的联合类型,比如 `int | str -> str`
+- 对类型上界 `any` 的转换,比如 `any -> int`
+- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema`
+
+```python
+schema Data1:
+ id?: int
+
+schema Data2:
+ name?: str
+
+data: Data1 | Data2 = Data1 {}
+
+if typeof(data) == "Data1":
+ data1 = data as Data1 # The type of `data` is `Data1`
+elif typeof(data) == "Data2":
+ data2 = data as Data2 # The type of `data` is `Data2`
+```
+
+当类型转换失败时,一个运行时错误将被抛出。
+
+```python
+a: any = "s"
+b: int = a as int # Error: The `str` type cannot be converted to the `int` type
+```
+
+如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。
+
+```python
+a: any = "s"
+b = a as int if typeof(a) == "int" else None # The type of b is `int`
+```
+
+请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。
+
+### Schema
+
+#### 概述
+
+Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。
+
+#### 基础部分
+
+##### 属性
+
+以下是 schema 基础定义的示例:
+
+```python
+# A person has a first name, a last name and an age.
+schema Person:
+ firstName: str
+ lastName: str
+ # The default value of age is 0
+ age: int = 0
+```
+
+在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。
+
+###### 不可变性
+
+schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改:
+
+```python
+schema Person:
+ age: int = 1 # Immutable attribute
+ _name: str = "Alice" # Mutable attribute
+
+ age = 10 # Error, can't change the default value of the attribute `age` in the schema context.
+ _name = "Bob" # Ok
+
+person = Person {
+ age = 3 # Ok, can change the default value of the attribute `age` in the schema config.
+}
+```
+
+###### 可选属性
+
+schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。
+
+示例:
+
+```python
+schema Employee:
+ bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined
+ nationality?: str # nationality is an optional attribute, and it can be None or Undefined
+
+employee = Employee {
+ bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined
+ nationality = None # Ok
+}
+```
+
+##### 顺序无关计算
+
+schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。
+
+由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。
+
+请注意,不同 schema 属性值之间不能有循环引用。
+
+我们可以通过下面的例子看到这个特性。
+
+```python
+schema Fib:
+ n1: int = n - 1 # Refers to the attribute `n` declared after `n1`
+ n2: int = n1 - 1
+ n: int
+ value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value
+
+fib8 = Fib {n = 8}.value
+```
+
+结果为:
+
+```yaml
+fib8: 21
+```
+
+在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。
+
+##### Schema 上下文
+
+我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等:
+
+```python
+schema Person[_name: str]: # define a schema argument
+ name: str = _name # define a schema attribute
+ age: int = 10 # define a schema attribute with default value
+ hands: [int] = [i for i in [1, 2, 3]] # define a for statement
+```
+
+然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量:
+
+```python
+alice = Person("alice")
+```
+
+可以得到如下 YAML 输出:
+
+```yaml
+alice:
+ name: alice
+ age: 10
+ hands:
+ - 1
+ - 2
+ - 3
+```
+
+##### 校验
+
+KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力):
+
+```python
+import regex
+
+schema Sample:
+ foo: str
+ bar: int
+ fooList: [str]
+
+ check:
+ bar > 0 # Minimum, also support the exclusive case
+ bar < 100 # Maximum, also support the exclusive case
+ len(fooList) > 0 # Min length, also support exclusive case
+ len(fooList) < 100 # Max length, also support exclusive case
+ regex.match(foo, "^The.*Foo$") # Regex match
+ isunique(fooList) # Unique
+ bar in range(100) # Range
+ bar in [2, 4, 6, 8] # Enum
+ multiplyof(bar, 2) # MultipleOf
+```
+
+使用 schema, 所有的实例将在编译时验证:
+
+```python
+# Ok
+goodSample = Sample {
+ foo = "The Foo"
+ bar = 2
+ fooList = ["foo0", "foo1"]
+}
+
+# Error: validation failure: Check failed on check conditions: bar < 100.
+badSample = Sample {
+ foo = "The Foo"
+ bar = 123
+ fooList = ["foo0", "foo1"]
+}
+```
+
+此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑:
+
+```python
+schema Sample:
+ bar: int
+ foo: str
+ doCheck: bool
+
+ check:
+ regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck
+```
+
+为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。
+
+##### 文档
+
+通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示:
+
+```python
+schema Server:
+ """Server is the common user interface for long-running
+ services adopting the best practice of Kubernetes.
+
+ Attributes
+ ----------
+ workloadType : str, default is Deployment
+ Use this attribute to specify which kind of long-running service you want.
+ Valid values: Deployment, CafeDeployment.
+ See also: k8s/core/v1/workload_metadata.k.
+ name : str, default is None
+ A Server-level attribute.
+ The name of the long-running service.
+ See also: k8s/core/v1/metadata.k.
+ labels : {str:str}, optional, default is None
+ A Server-level attribute.
+ The labels of the long-running service.
+ See also: k8s/core/v1/metadata.k.
+
+ Examples
+ ----------------------
+ myCustomApp = AppConfiguration {
+ name = "componentName"
+ }
+ """
+ workloadType: str = "Deployment"
+ name: str
+ labels?: {str:str}
+```
+
+更多详细内容可见 Doc tools。
+
+##### 配置
+
+假设我们有如下 schema 定义:
+
+```python
+schema Person:
+ firstName: str
+ lastName: str
+ labels?: {str:str}
+```
+
+可以用类 JSON 的表达式定义配置:
+
+```python
+person = Person {
+ firstName = "firstName"
+ lastName = "lastName"
+}
+```
+
+schema 遵循严格的属性定义,配置未定义的属性将触发编译错误:
+
+```python
+person = Person {
+ firstName = "firstName"
+ lastName = "lastName"
+ fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person'
+}
+```
+
+此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。
+
+```python
+env = "prod"
+person = Person {
+ firstName = "firstName"
+ lastName = "lastName"
+ if env == "prod":
+ labels.env = env
+ else:
+ labels.env = "other"
+}
+# We can use the person instance to get a new instance named `personx` directly.
+personx = person {
+ firstName = "NewFirstName"
+}
+```
+
+输出为:
+
+```yaml
+env: prod
+person:
+ firstName: firstName
+ lastName: lastName
+ labels:
+ env: prod
+personx:
+ firstName: NewFirstName
+ lastName: lastName
+ labels:
+ env: prod
+```
+
+#### 高级功能
+
+##### Protocol & Mixin
+
+除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下:
+
+- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。
+- protocol 只能对非 `_` 开头的属性进行约束。
+- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。
+
+此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。
+
+```python
+schema Person:
+ mixin [FullNameMixin]
+
+ firstName: str # Required
+ lastName: str # Required
+ fullName?: str # Optional
+```
+
+FullNameMixin 是一个产生 fullName 字段的简单例子:
+
+```python
+protocol PersonProtocol:
+ firstName: str
+ lastName: str
+ fullName?: str
+
+mixin FullNameMixin for PersonProtocol:
+ fullName = "{} {}".format(firstName, lastName)
+```
+
+然后我们可以通过一下方式获取 schema 实例:
+
+```python
+person = Person {
+ firstName = "John"
+ lastName = "Doe"
+}
+```
+
+输出结果为:
+
+```yaml
+person:
+ firstName: John
+ lastName: Doe
+ fullName: John Doe
+```
+
+请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。
+
+```python
+protocol DataProtocol:
+ data: str
+
+schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol
+ x: str = data
+```
+
+##### 索引签名
+
+在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。
+
+###### 基本用法
+
+使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。
+
+```python
+schema Map:
+ """
+ Map is a schema with a key of str type and a value of str type
+ """
+ [str]: str # `{attr_alias}` can be omitted.
+
+data = Map {
+ key1 = "value1"
+ key2 = "value2"
+}
+```
+
+###### 同时定义属性和索引签名
+
+可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码
+
+```python
+schema Person:
+ name: str
+ age: int
+ [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`.
+```
+
+###### 定义索引签名别名
+
+- 可以为索引签名定义类型注解的属性别名,并将其与索引签名的默认值一起使用。
+
+```python
+schema Environment:
+ [id: str]: EnvironmentSpec = {
+ fullName = id
+ }
+
+schema EnvironmentSpec:
+ fullName: str
+ shortName: str = fullName
+ accountID: int
+
+environment = Environment {
+ development: {
+ shortName: "dev"
+ accountID: 123456
+ }
+ production: {
+ shortName: "prod"
+ accountID: 456789
+ }
+}
+```
+
+YAML 输出为:
+
+```yaml
+environment:
+ production:
+ fullName: production
+ shortName: prod
+ accountID: 456789
+ development:
+ fullName: development
+ shortName: dev
+ accountID: 123456
+```
+
+- 可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。
+
+```python
+schema Data:
+ [dataName: str]: str
+ check:
+ dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block.
+
+data = Data {
+ Alice = "10"
+ Bob = "12"
+ Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"]
+}
+```
+
+```python
+import regex
+
+schema DataMap:
+ [attr: str]: str
+ check:
+ regex.match(attr, r'^[-_a-zA-Z0-9]+$')
+
+data = DataMap {
+ key1 = "value1"
+ "foo.bar" = "value2" # check error
+}
+```
+
+##### 继承
+
+类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。
+
+以下是单继承的例子:
+
+```python
+# A person has a first name, a last name and an age.
+schema Person:
+ firstName: str
+ lastName: str
+ # The default value of age is 0
+ age: int = 0
+
+# An employee **is** a person, and has some additional information.
+schema Employee(Person):
+ bankCard: int
+ nationality?: str
+
+employee = Employee {
+ firstName = "Bob"
+ lastName = "Green"
+ age = 18
+ bankCard = 123456
+}
+```
+
+结果为:
+
+```yaml
+employee:
+ firstName: Bob
+ lastName: Green
+ age: 18
+ bankCard: 123456
+ nationality: null
+```
+
+请注意,KCL 只支持 schema 的 **单继承**。
+
+此外,当 schema 存在继承关系时,可选属性的性质如下:
+
+- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。
+- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。
+
+```python
+schema Person:
+ bankCard?: int
+ nationality: str
+
+schema Employee(Person):
+ bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed
+ nationality?: str # Error, only `nationality: str` is allowed
+```
+
+##### Schema 函数
+
+schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写:
+
+```python
+schema Fib[n: int]:
+ n1 = n - 1
+ n2 = n - 2
+ if n == 0:
+ value = 0
+ elif n == 1:
+ value = 1
+ else:
+ value = Fib(n1).value + Fib(n2).value
+
+fib8 = Fib(8).value # 21
+```
+
+##### 装饰器
+
+像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。
+
+内置的 schema 装饰器:
+
+- `@deprecated`
+ 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数:
+ - **version** - 字符串类型,表示版本信息。 默认值为空。
+ - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。
+ - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。
+
+示例:
+
+```python
+@deprecated
+schema ObsoleteSchema:
+ attr: str
+
+schema Person:
+ firstName: str = "John"
+ lastName: str
+ @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True)
+ name: str
+ attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated
+ attr = "value"
+ }
+
+JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead
+ name = "deprecated"
+}
+```
+
+- `@info`
+ 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息
+
+示例:
+
+```python
+@info(version="v1")
+schema Person:
+ @info(message="name")
+ name: str
+ age: int
+```
+
+请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。
+
+##### 成员函数
+
+内置函数和 schema 成员
+
+- instances(full_pkg: bool = False)
+ 返回 schema 的现有实例列表,当 `full_pkg` 设置为 `False` 时,仅返回 main 中的 schema 实例,当 `full_pkg` 设置为 `True` 时,返回整个项目对应 schema 的所有实例。
+
+```python
+schema Person:
+ name: str
+ age: int
+
+alice = Person {
+ name = "Alice"
+ age = 18
+}
+
+bob = Person {
+ name = "Bob"
+ age = 10
+}
+
+aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method
+```
+
+输出为:
+
+```yaml
+alice:
+ name: Alice
+ age: 18
+bob:
+ name: Bob
+ age: 10
+aliceAndBob:
+ - name: Alice
+ age: 18
+ - name: Bob
+ age: 10
+```
+
+### 配置操作
+
+#### 配置合并
+
+##### | 运算符
+
+在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下:
+
+```txt
+SchemaInstance | SchemaInstance
+SchemaInstance | Dict
+Dict | Dict
+List | List
+```
+
+合并集合和结构化数据:
+
+- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。
+
+```python
+_a = [1, 2, 3]
+_b = [4, 5, 6, 7]
+x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7
+```
+
+合并特定索引或所有元素仍在讨论中。
+
+- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。
+
+```python
+_a = {key1 = "value1"}
+_b = {key1 = "overwrite", key2 = "value2"}
+x = _a | _b # {"key1": "overwrite", "key2": "value2"}
+```
+
+集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。
+
+- 合并 schema。Schema 的合并与 dict 相似。
+
+Schema 的合并操作如下:
+
+```python
+schema Person:
+ firstName?: str
+ lastName?: str
+
+_a = Person {
+ firstName = "John"
+}
+_b = {lastName = "Doe"}
+_c = _a | _b # {"firstName": "John", "lastName": "Doe"}
+_d = _a | None # {"firstName": "John"}
+_e = _a | Undefined # {"firstName": "John"}
+_f = None | _a # {"firstName": "John"}
+_g = Undefined | _a # {"firstName": "John"}
+```
+
+请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。
+
+```python
+data1 = {key = "value"} | None # {"key": "value"}
+data2 = None | [1, 2, 3] # [1, 2, 3]
+data3 = None | None # None
+```
+
+输出如下:
+
+```yaml
+data1:
+ key: value
+data2:
+ - 1
+ - 2
+ - 3
+data3: null
+```
+
+##### : 运算符
+
+模式: `identifier : E`
+
+表达式 `E` 的值将被合并到元素值。
+
+示例:
+
+```python
+schema Data:
+ labels: {str:} = {key1 = "value1"}
+
+data = Data {
+ # union {key2: "value2"} into the attribute labels of the schema Data.
+ labels: {key2 = "value2"}
+}
+```
+
+输出:
+
+```yaml
+data:
+ labels:
+ key1: value1
+ key2: value2
+```
+
+除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。
+
+- schema 外部使用合并运算符 `:`
+
+```python
+schema Data:
+ d1?: int
+ d2?: int
+
+schema Config:
+ data: Data
+
+# This is one configuration that will be merged.
+config: Config {
+ data.d1 = 1
+}
+# This is another configuration that will be merged.
+config: Config {
+ data.d2 = 2
+}
+```
+
+与它等效的配置代码可以表示为:
+
+```python
+schema Data:
+ d1?: int
+ d2?: int
+
+schema Config:
+ data: Data
+
+config: Config {
+ data.d1 = 1
+ data.d2 = 1
+}
+```
+
+输出结果为:
+
+```yaml
+config:
+ data:
+ d1: 1
+ d2: 1
+```
+
+- schema 内部使用合并运算符 `:`
+
+```python
+schema Data:
+ d1?: int
+ d2?: int
+
+schema Config:
+ # This is one configuration that will be merged.
+ data: Data {
+ d1 = 1
+ }
+ # This is another configuration that will be merged.
+ data: Data {
+ d2 = 1
+ }
+
+config: Config {}
+```
+
+#### 配置覆盖
+
+##### = 运算符
+
+模式: `identifier = E`
+
+表达式 `E` 的值将覆盖元素值。
+
+示例:
+
+```python
+schema Data:
+ labels: {str:} = {key1 = "value1"}
+
+data = Data {
+ # override {key2: "value2"} into the attribute labels of the schema Data.
+ labels = {key2 = "value2"}
+}
+```
+
+输出:
+
+```yaml
+data:
+ labels:
+ key2: value2
+```
+
+请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。
+
+#### 配置添加
+
+##### += 运算符
+
+模式: `identifier += E`
+
+插入只能用于列表类型的 `identifier`.
+
+`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。
+
+示例:
+
+```python
+schema Data:
+ labels: {str:} = {key1 = [0, 1, 3]}
+
+data = Data {
+ # insert [3] after the index 1 of the attribute labels.key1 of the schema Data.
+ labels: {key1[1] += [2]}
+}
+```
+
+输出:
+
+```yaml
+data:
+ labels:
+ key1:
+ - 0
+ - 1
+ - 2
+ - 3
+```
+
+如果没有定义索引,将使用最后一个索引。
+
+#### 注意事项
+
+合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。
+
+```python
+data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1}
+data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2}
+```
+
+`:` 运算符冲突检查的规则如下:
+
+- `None` 和 `Undefined` 不与任何值冲突
+
+```python
+data0 = None | {id: 1} # Ok
+```
+
+- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。
+
+```python
+data0 = 1 | 1 # Ok
+data1 = 1 | "s" # Error
+```
+
+- 对于列表类型
+ - 当它们的长度不相同时,它们被认为是冲突的
+ - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的
+
+```python
+data0 = [1] | [1] # Ok
+data1 = [1, 2] | [1] # Error
+```
+
+- 对于 dict/schema 类型
+ - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的
+
+```python
+data0 = {id: 1} | {id: 1} # Ok
+data1 = {id: 1} | {id: 2} # Error
+data1 = {id: 1} | {idAnother: 1} # Ok
+```
+
+### Rule
+
+KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。
+
+```python
+rule SomeRule:
+ age > 0, "rule check failure message"
+```
+
+可以像 schema 实例化那样调用一个 rule 进行校验
+
+```python
+age = 0
+name = "Bob"
+rule SomeRule:
+ age > 0, "rule check failure message"
+ name == "Alice"
+
+rule1 = SomeRule() # Rule call
+rule2 = SomeRule {}
+```
+
+可以使用 protocol 和 for 绑定语句为 rule 增加类型约束:
+
+```python
+# Protocol definition
+protocol ServiceProtocol:
+ clusterIp: str
+ $type: str
+
+# Protocol definition
+protocol VolumeProtocol:
+ mountPath: str
+
+# Protocol
+protocol SomeProtocol:
+ id: int
+ env: {str: any}
+ services: [ServiceProtocol]
+ volumes: [VolumeProtocol]
+
+rule SomeChecker for SomeProtocol:
+ id > 0, "id must >0"
+
+ all service in services {
+ service.clusterIp == "NONE" if service.type == "ClusterIP"
+ }
+
+ any volume in volumes {
+ volume.mountPath in ["/home/admin", "/home/myapp"]
+ }
+
+# Call rule to check with config parameter
+SomeChecker {
+ id = 1
+ env = {
+ MY_ENV = "MY_ENV_VALUE"
+ }
+ services = [
+ {
+ type = "ClusterIP"
+ clusterIp = "NONE"
+ }
+ ]
+ volumes = [
+ {
+ mountPath = "/home/admin"
+ }
+ {
+ mountPath = "/home/myapp"
+ }
+ ]
+}
+```
+
+请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。
+
+此外,有两种复用不同 rule 的方式
+
+- 直接调用
+
+```python
+weather = "sunny"
+day = "wednesday"
+
+rule IsSunny:
+ weather == "sunny"
+
+rule IsWednesday:
+ day == "wednesday"
+
+rule Main:
+ IsSunny() # Rule inline call
+ IsWednesday() # Rule inline call
+
+Main() # Rule call
+```
+
+使用 rule 的继承 (rule 不同于 schema, 可以多继承混用)
+
+```python
+weather = "sunny"
+day = "wednesday"
+
+rule IsSunny:
+ weather == "sunny"
+
+rule IsWednesday:
+ day == "wednesday"
+
+rule Main(IsSunny, IsWednesday):
+ id == 1
+
+Main()
+```
+
+可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验
+
+- 一个简单例子
+
+```python
+schema Day:
+ day: str
+ homework: str
+
+days: [Day] = option("days")
+
+rule Main:
+ filter d in days {
+ d.day not in ["saturday", "sunday"] and d.homework
+ }
+
+Main()
+```
+
+- 一个复杂例子
+
+```python
+data = option("data")
+input = option("input")
+
+rule Allow:
+ UserIsAdmin()
+ any grant in UserIsGranted() {
+ input.action == grant.action and input.type == grant.type
+ }
+
+rule UserIsAdmin:
+ any user in data.user_roles[input.user] {
+ user == "admin"
+ }
+
+rule UserIsGranted:
+ [
+ grant
+ for role in data.user_roles[input.user]
+ for grant in data.role_grants[role]
+ ]
+
+allow = Allow() or False
+```
+
+### 模块
+
+KCL 配置文件以 **模块 (module)** 形式组织。 单个 KCL 文件被认为是一个模块,一个目录被认为是一个包。
+
+同一个包内的模块是可见的,跨包引用需要通过导入可见。
+
+```bash
+.
+└── root
+ ├── model
+ │ ├── model1.k
+ | ├── model2.k
+ │ └── main.k
+ ├── service
+ │ └── service1.k
+ └── mixin
+ └── mixin1.k
+```
+
+model1.k:
+
+```python
+# schema CatalogItem in model1.k
+
+schema CatalogItem:
+ id: int
+ image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model
+ title: str
+```
+
+service1.k:
+
+```python
+import ..model as model # cross-package references
+
+schema ImageService:
+ image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model
+ name: str
+```
+
+#### 相对路径引用
+
+我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。
+
+main.k:
+
+```python
+import .model1 # Current directory module
+import ..service # Parent directory
+import ...root # Parent of parent directory
+
+s = service.ImageService {}
+m = root.Schema {}
+```
+
+#### 绝对路径引用
+
+`import a.b.c.d` 的语义为:
+
+1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径
+2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误
+
+根路径 `ROOT_PATH` 的定义为:
+
+从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。
+
+```bash
+.
+└── root
+ ├── kcl.mod
+ ├── model
+ │ ├── model1.k
+ | ├── model2.k
+ │ └── main.k
+ ├── service
+ │ └── service1.k
+ └── mixin
+ └── mixin1.k
+```
+
+main.k:
+
+```python
+import service # `root package` and `kcl.mod` are in the same directory
+import mixin # `root package` and `kcl.mod` are in the same directory
+
+myModel = model.CatalogItem {}
+```
+
+请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误:
+
+```python
+import model # Error: recursively loading
+```
+
+### 动态参数
+
+假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数:
+
+```python
+bankCard = option("bankCard") # Get bankCard through the option function.
+```
+
+我们可以如下使用 module:
+
+```bash
+kcl employee.k -D bankCard=123
+```
+
+目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。
+
+```bash
+kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}'
+```
+
+请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义
+
+#### Setting 文件形式的参数
+
+此外,它还支持输入一个 YAML 文件作为顶级参数。
+
+```yaml
+kcl_options:
+ - key: key_number
+ value: 1
+ - key: key_dict
+ value:
+ innerDictKey: innerDictValue
+ - key: key_list
+ value:
+ - 1
+ - 2
+ - 3
+ - key: bankCard
+ value: 123
+```
+
+```bash
+kcl -Y setting.yaml employee.k
+```
+
+此外,setting 文件还支持配置命令行编译参数如下:
+
+```yaml
+kcl_cli_configs:
+ files:
+ - file1.k
+ - file2.k
+ disable_none: true
+ strict_range_check: true
+ debug: 1
+ verbose: 1
+ sort_keys: true
+ output: ./stdout.golden
+ overrides:
+ - app.image=new_image
+ path_selector:
+ - config
+ package_maps:
+ k8s: /Users/.kcl/kpm/k8s_1.24
+kcl_options:
+ - key: image
+ value: docker.io/kcllang/kcl:latest
+```
+
+KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。
+
+```bash
+kcl -Y compile_setting.yaml option_setting.yaml
+```
+
+- `compile_setting.yaml`
+
+```yaml
+kcl_cli_configs:
+ files:
+ - file1.k
+ - file2.k
+ disable_none: true
+ strict_range_check: true
+ debug: 1
+ verbose: 1
+ output: ./stdout.golden
+```
+
+- `option_setting.yaml`
+
+```yaml
+kcl_options:
+ - key: image
+ value: docker.io/kcllang/kcl:latest
+```
+
+我们可以使用以下指令获取每个参数的含义
+
+```bash
+kcl --help
+```
+
+#### Option Functions
+
+我们可以在 KCL 代码中使用 `option` 获取顶级参数。
+
+```python
+value = option(key="key", type='str', default="default_value", required=True, help="Set key value")
+```
+
+参数
+
+- **key**: 参数的键。
+- **type**: 要转换的参数类型。
+- **default**: 参数默认值。
+- **required**: 当未提供参数和缺省值,且参数的 required 为 True 时报告错误。
+- **help**: 帮助信息。
+
+### 多文件编译
+
+除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件:
+
+```bash
+kcl main_1.k main_2.k ... main_n.k
+```
+
+main_1.k
+
+```python
+a = 1
+b = 2
+```
+
+main_2.k
+
+```python
+c = 3
+d = 4
+```
+
+输出结果为:
+
+```yaml
+a: 1
+b: 2
+c: 3
+d: 4
+```
+
+利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。
+
+model.k
+
+```python
+schema Model:
+ name: str
+ labels?: {str:}
+ annotations?: {str:}
+ replicas: int
+
+_model1 = Model {
+ name = "model1"
+ labels.key1 = "value1"
+ labels.key2 = "value2"
+ annotations.key = "value"
+ replicas = 2
+}
+
+_model2 = Model {
+ name = "model2"
+ replicas = 3
+}
+```
+
+backend.k
+
+```python
+import manifests
+
+schema Backend:
+ apiVersion: str = "v1"
+ kind: str = "Deployment"
+ metadata: {str:}
+ spec: {str:} = {
+ minReadySeconds = 0
+ paused = False
+ progressDeadlineSeconds = 600
+ replicas = 1
+ revisionHistoryLimit = 10
+ selector = {}
+ }
+
+_backends = [Backend {
+ metadata.name = model.name
+ metadata.labels = model.labels
+ metadata.annotations = model.annotations
+ spec.selector.matchLabels: model.labels
+ spec.replicas = model.replicas
+} for model in Model.instances()] # Schema Model is defined in model.k
+
+manifests.yaml_stream(_backends)
+```
+
+命令为:
+
+```bash
+kcl model.k backend.k
+```
+
+输出为:
+
+```yaml
+apiVersion: v1
+kind: Deployment
+metadata:
+ name: model1
+ labels:
+ key1: value1
+ key2: value2
+ annotations:
+ key: value
+spec:
+ minReadySeconds: 0
+ paused: false
+ progressDeadlineSeconds: 600
+ replicas: 2
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ key1: value1
+ key2: value2
+---
+apiVersion: v1
+kind: Deployment
+metadata:
+ name: model2
+spec:
+ minReadySeconds: 0
+ paused: false
+ progressDeadlineSeconds: 600
+ replicas: 3
+ revisionHistoryLimit: 10
+ selector: {}
+```
+
+### KCL 变量查询
+
+我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。
+
+变量查询形式如下:
+
+`var.name`
+
+#### 示例
+
+Code structure:
+
+```bash
+.
+├── kcl.mod
+└── main.k
+ └── pkg
+ └── model.k
+```
+
+pkg/model.k:
+
+```python
+schema Person:
+ name: str
+ age: int
+
+var = Person {
+ name = "Alice"
+ age = 18
+}
+```
+
+main.k
+
+```python
+import pkg
+
+var = pkg.Person {
+ name = "Bob"
+ age = 10
+}
+```
+
+命令为:
+
+```bash
+kcl main.k -S var
+```
+
+输出结果为:
+
+```yaml
+var:
+ name: Bob
+---
+var:
+ name: Alice
+ age: 18
+```
+
+### KCL 变量修改
+
+除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。
+
+变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` .
+
+```bash
+kcl main.k -O override_spec
+```
+
+- `override_spec`: 表示需要修改的配置模型字段和值的统一表示
+
+```bash
+override_spec: identifier (("=" | ":" | "+=") value | "-")
+```
+
+- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 或者 `a["dot.key"].c` 的形式
+- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等
+- `=`, `-` 和 `+=`: 表示用对应的属性运算符修改 identifier 的值
+ - 当 identifier 存在时,修改已有 identifier的值为 value
+ - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value
+- `-`: 表示删除 identifier属性
+ - 当 identifier 存在时,直接进行删除
+ - 当 identifier 不存在时,对配置不作任何修改
+
+请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值
+
+此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md)
+
+#### 示例
+
+##### 修改示例
+
+KCL 代码:
+
+```python
+schema Person:
+ name: str
+ age: int
+
+person = Person {
+ name = "Alice"
+ age = 18
+}
+```
+
+命令为:
+
+```bash
+kcl main.k -O :person.name=Bob -O :person.age=10
+```
+
+输出结果为:
+
+```yaml
+person:
+ name: Bob
+ age: 10
+```
+
+此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容
+
+```bash
+kcl main.k -O :person.name=Bob -O :person.age=10 -d
+```
+
+```python
+schema Person:
+ name: str
+ age: int
+
+person = Person {
+ name = "Bob"
+ age = 10
+}
+```
+
+##### 删除示例
+
+KCL 代码:
+
+```python
+schema Config:
+ x?: int = 1
+ y?: str = "s"
+
+config = Config {
+ x = 2
+}
+```
+
+命令为:
+
+```bash
+kcl main.k -O config.x-
+```
+
+输出结果为:
+
+```yaml
+config:
+ y: s
+```
+
+### 总结
+
+本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/_category_.json
new file mode 100644
index 000000000..a8f409150
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "类型系统",
+ "position": 4
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/types.md
new file mode 100644
index 000000000..182ffaf2b
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/lang/types/types.md
@@ -0,0 +1,1401 @@
+# 类型系统
+
+本文档描述 KCL 的类型系统,包括:
+
+- 类型规则
+- 类型检查
+- 类型转换
+- 类型推导
+
+## 类型规则
+
+### 基础定义
+
+#### 断言
+
+$S$ 的所有自由变量都定义在 $\Gamma$ 中
+
+$$
+\Gamma \vdash S
+$$
+
+$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$
+
+$S$ 的断言有三种形式:
+
+**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type)
+
+$$
+\Gamma \vdash ◇
+$$
+
+**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式
+
+$$
+\Gamma \vdash nat
+$$
+
+**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$
+
+$$
+\Gamma \vdash E: T
+$$
+
+#### 推理规则
+
+表示法
+
+$$
+\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S}
+$$
+
+推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。
+
+## 环境规则
+
+Env ⌀
+
+$$
+\frac{}{⌀ \vdash ◇ }
+$$
+
+## 类型定义
+
+Type Bool
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean}
+$$
+
+Type Int
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash integer}
+$$
+
+Type Float
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash float}
+$$
+
+Type String
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash string}
+$$
+
+Type Literal
+
+$$
+\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)}
+$$
+
+Type List
+
+$$
+\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) }
+$$
+
+Type Dict
+
+$$
+\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)}
+$$
+
+Type Struct
+
+$$
+\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})}
+$$
+
+Type Union
+
+$$
+\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)}
+$$
+
+Type None
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash None}
+$$
+
+Type Undefined
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined}
+$$
+
+Type Void
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash Void}
+$$
+
+Type Any
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash Any}
+$$
+
+Type Nothing
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing}
+$$
+
+## 类型判断规则
+
+### Operand Expr
+
+Exp Truth
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean}
+$$
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean}
+$$
+
+Exp Int
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer}
+$$
+
+Exp Flt
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float}
+$$
+
+Exp Str
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string}
+$$
+
+Exp None
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none}
+$$
+
+Exp Undefined
+
+$$
+\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined}
+$$
+
+Expr ListExp
+
+$$
+\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)}
+$$
+
+Expr ListComp
+
+$$
+\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) }
+$$
+
+Expr DictExp
+
+$$
+\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))}
+$$
+
+Expr DictComp
+
+$$
+\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) }
+$$
+
+Expr StructExpr
+
+$$
+\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})}
+$$
+
+Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。
+
+### Primary Expr
+
+Expr Index
+
+$$
+\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T}
+$$
+
+Expr Call
+
+$$
+\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2}
+$$
+
+Expr List Selector
+
+$$
+\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T}
+$$
+
+Expr Dict Selector
+
+$$
+\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)}
+$$
+
+Expr Struct Selector
+
+$$
+\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}}
+$$
+
+### Unary Expr
+
+Expr +
+
+$$
+\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T}
+$$
+
+Expr -
+
+$$
+\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T}
+$$
+
+Expr ~
+
+$$
+\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer}
+$$
+
+Expr not
+
+$$
+\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean}
+$$
+
+### Binary Expr
+
+算数运算符
+
+Expr op, op $\in$ {-, /, %, \*\*, //}
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T}
+$$
+
+Expr +
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T}
+$$
+
+Expr \*
+
+$$
+\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T}
+$$
+
+示例
+
+Expr %
+
+$$
+\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger}
+$$
+
+逻辑运算符
+
+Expr op, op $\in$ \{or, and\}
+
+$$
+\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean}
+$$
+
+示例
+
+Expr and
+
+$$
+\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean}
+$$
+
+比较运算符
+
+Expr op, op $\in$ \{==, !=, <, >, <=, >=\}
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean}
+$$
+
+示例
+
+Expr >
+
+$$
+\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean}
+$$
+
+位运算符
+
+Expr op, op $\in$ {&, ^, ~, <<, >>}
+
+$$
+\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer}
+$$
+
+Expr |
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T}
+$$
+
+成员运算符
+
+Expr op, op $\in$ {in, not in}
+
+$$
+\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool}
+$$
+
+Expr op, op $\in$ {in, not in}
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool}
+$$
+
+身份运算符
+
+Expr op $\in$ {is, is not}
+
+$$
+\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool}
+$$
+
+### IF Expr
+
+Expr If
+
+$$
+\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T}
+$$
+
+### Stmt
+
+Stmt If
+
+$$
+\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void}
+$$
+
+Stmt Assign
+
+$$
+\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void}
+$$
+
+Type Alias
+
+$$
+\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void}
+$$
+
+## Union
+
+### Union 规则
+
+List Union
+
+$$
+\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))}
+$$
+
+Dict Union
+
+$$
+\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))}
+$$
+
+Struct Union
+
+给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$
+
+定义他们的 union 类型:
+
+$$
+structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})
+$$
+
+例如:
+
+$$
+structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n})
+$$
+
+$$
+structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}))
+$$
+
+其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下:
+
+$$
+structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1})
+$$
+
+$$
+structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n})
+$$
+
+$$
+structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n})
+$$
+
+基于此,两个 Struct 的 union 定义为:
+
+$$
+\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))}
+$$
+
+其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作:
+
+- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界
+- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑:
+ - 结构体 union 失败,返回 type_error
+ - 返回后者的类型,此处为 $T_2$
+ - 返回类型 $unionof(T_1, T_2)$
+
+此处需要根据实际需求选择适当的处理方式。
+
+结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下:
+
+- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准
+- 否则返回 type_error
+
+通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。
+
+## Operation
+
+KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。
+
+定义如下更新操作:
+
+$$
+\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})} {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T} k \neq k_1, ..., k \neq k_n}
+{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}}
+$$
+
+即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么
+
+$$
+\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})} {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1} k \neq k_1, ..., k \neq k_n}
+{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}}
+$$
+
+注意:
+
+- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。
+- 对于多层结构体嵌套的操作,递归的使用以上规则即可。
+
+## 类型偏序
+
+### 基础类型
+
+$$
+Type \ T \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ T
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Int \sqsubseteq Type \ Float
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Any
+$$
+
+### 字面值类型
+
+$$
+Type \ Literal(Bool) \sqsubseteq Type \ Bool
+$$
+
+$$
+Type \ Literal(Int) \sqsubseteq Type \ Int
+$$
+
+$$
+Type \ Literal(Float) \sqsubseteq Type \ Float
+$$
+
+$$
+Type \ Literal(String) \sqsubseteq Type \ String
+$$
+
+### 联合类型
+
+$$
+Type \ X \sqsubseteq Type \ Union(X, Y)
+$$
+
+### 自反
+
+$$
+Type \ X \sqsubseteq Type \ X
+$$
+
+示例
+
+$$
+Type \ Bool \sqsubseteq Type \ Bool
+$$
+
+$$
+Type \ Int \sqsubseteq Type \ Int
+$$
+
+$$
+Type \ Float \sqsubseteq Type \ Float
+$$
+
+$$
+Type \ String \sqsubseteq Type \ String
+$$
+
+$$
+Type \ List \sqsubseteq Type \ List
+$$
+
+$$
+Type \ Dict \sqsubseteq Type \ Dict
+$$
+
+$$
+Type \ Struct \sqsubseteq Type \ Struct
+$$
+
+$$
+Type \ Nothing \sqsubseteq Type \ Nothing
+$$
+
+$$
+Type \ Any \sqsubseteq Type \ Any
+$$
+
+$$
+Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool)
+$$
+
+### 传递
+
+$$
+Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z
+$$
+
+### 包含
+
+$$
+Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2
+$$
+
+$$
+Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1}
+$$
+
+$$
+Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn}
+$$
+
+### 继承
+
+$$
+Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B
+$$
+
+### None
+
+$$
+Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\}
+$$
+
+### Undefined
+
+$$
+Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\}
+$$
+
+## 相等性
+
+交换律
+
+$$
+Type \ Union(X, Y) == Type \ Union(Y, X)
+$$
+
+示例
+
+$$
+Type \ Union(Int, Bool) == Type \ Union(Bool, Int)
+$$
+
+结合律
+
+$$
+Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z))
+$$
+
+示例
+
+$$
+Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool))
+$$
+
+幂等性
+
+$$
+Type \ Union(X, X) == Type \ X
+$$
+
+示例
+
+$$
+Type \ Union(Int, Int) == Type \ Int
+$$
+
+偏序推导
+
+$$
+Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y
+$$
+
+示例
+
+假设 Struct A 继承 Struct B
+
+$$
+Type \ Union(A, B) == Type \ B
+$$
+
+幂等性是偏序自反的一个特例
+
+### List
+
+$$
+Type \ List(X) == Type \ List(Y) \ if \ X == Y
+$$
+
+### Dict
+
+$$
+Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v
+$$
+
+### Struct
+
+$$
+Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n}
+$$
+
+### 偏序检查
+
+$$
+Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X
+$$
+
+## 基础方法
+
+- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。
+- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。
+- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。
+
+### Sup Function
+
+- 暂不考虑类型参数,条件类型等特性
+- 使用一个有序集合存储 UnionType 的所有类型
+- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType
+- 根据偏序关系计算类型之间的包含关系
+
+```go
+// The Sup function returns the minimum supremum of all types in an array of types
+func Sup(types: T[]) -> T {
+ typeOf(types, removeSubTypes=true)
+}
+
+// Build a sup type from types [T1, T2, ... , Tn]
+func typeOf(types: T[], removeSubTypes: bool = false) -> T {
+ assert isNotNullOrEmpty(types)
+ // 1. Initialize an ordered set to store the type array
+ typeSet: Set[T] = {}
+ // 2. Add the type array to the ordered set for sorting by the type id and de-duplication
+ addTypesToTypeSet(typeSet, types)
+ // 3. Remove sub types according to partial order relation rules e.g. sub schema types
+ if removeSubTypes {
+ removeSubTypes(typeSet)
+ }
+ if len(typeSet) == 1 {
+ // If the typeSet has only one type, return it
+ return typeSet[0]
+ }
+ // 4. Get or set the union type from the global union type map
+ id := getIdentifierFromTypeSet(typeSet)
+ unionType := globalUnionTypeMap.get(id)
+ if !unionType {
+ unionType = createUnionType(typeSet) // Build a new union type
+ globalUnionTypeMap.set(id, unionType)
+ }
+ return unionType
+}
+
+// Add many types into the type set
+func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void {
+ for type in types {
+ addTypeToTypeSet(typeSet, type)
+ }
+}
+
+// Add one type into the type set
+func addTypeToTypeSet(typeSet: Set[T], type: T) -> void {
+ if isUnion(type) {
+ return addTypesToTypeSet(typeSet, toUnionOf(type).types)
+ }
+ // Ignore the void type check
+ if !isVoid(type) {
+ // De-duplication according to the type of id
+ typeSet.add(type)
+ }
+}
+
+func removeSubTypes(types: Set[T]) -> void {
+ for source in types {
+ for target in types {
+ if !typeEqual(source, target) {
+ // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table.
+ if (isPartialOrderRelatedTo(source, target)) {
+ types.remove(source)
+ }
+ }
+ }
+ }
+}
+
+// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target`
+// according to the partial order relationship table and rules
+func isPartialOrderRelatedTo(source: T, target: T) -> bool {
+ assert isNotNullOrEmpty(source)
+ assert isNotNullOrEmpty(target)
+ if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) {
+ return true
+ }
+ if isAny(target) {
+ return true
+ }
+ if typeEqual(source, target) {
+ return true
+ }
+ if isUnion(target) and source in target.types {
+ return true
+ }
+ // Literal Type
+ if (isStringLiteral(source) and isString(target)) or \
+ (isBooleanLiteral(source) and isBool(target)) or \
+ (isIntLiteral(source) and isInt(target)) or \
+ (isFloatLiteral(source) and isFloat(target)) {
+ return true
+ }
+ if isInt(source) and isFloat(target) {
+ return true
+ }
+ if isList(source) and isList(target) {
+ return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType
+ }
+ if isDict(source) and isDict(target) {
+ return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType)
+ }
+ if isStruct(source) and isStruct(target) {
+ if isTypeDerivedFrom(source, target) {
+ return true
+ }
+ // Empty Object
+ if len(target.keys) == 0 {
+ return true
+ }
+ if any([key Not in source.keys for key in target.keys]) {
+ return false
+ }
+ for key, sourceType in (source.keys, source.types) {
+ targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf()
+ if !isPartialOrderRelatedTo(sourceType, targetType) {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
+```
+
+## 类型检查
+
+### 类型检查器
+
+类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。
+
+类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。
+
+### 基础方法
+
+1. isUpperBound(t1, t2): supUnify(t1, t2) == t2
+2. supUnify(t1, t2):
+
+- 对于基础类型,根据偏序关系计算 sup(t1, t2)
+- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify
+- 不存在偏序关系时,返回 Nothing
+
+### 检查逻辑
+
+#### Operand Expr
+
+$D \to id: T$
+
+```
+env.addtype(id.entry, T.type)
+```
+
+$T \to boolean$
+
+```
+T.type = boolean
+```
+
+$T \to integer$
+
+```
+T.type = integer
+```
+
+$T \to float$
+
+```
+T.type = float
+```
+
+$T \to string$
+
+```
+T.type = string
+```
+
+$T \to c, \ c \in \{boolean, integer, float, string\}$
+
+```
+T.type = literalof(c)
+```
+
+$T \to None$
+
+```
+T.type = None
+```
+
+$T \to Undefined$
+
+```
+T.type = Undefined
+```
+
+$T \to \ [T_1]$
+
+```
+T.type = listof (T1.type)
+```
+
+$T \to { \{T_1: T_2\} }$
+
+```
+T.type = dictof (T1.type: T2.type)
+```
+
+$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$
+
+```
+T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type)
+```
+
+$E \to id$
+
+```
+E.type = env.lookup(id.entry)
+```
+
+$E \to [E_1, E_2, ..., E_n]$
+
+```
+func listExpr(E) {
+ supe = sup([e.type for e in E]])
+ E.type = listof(type)
+}
+```
+
+$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$
+
+```
+func listComp(E) {
+ if !typeEqual(E4.type, boolean) {
+ raise type_error
+ }
+ if !isUpperBound(listof(Any), E3.type) {
+ raise type_error(E)
+ }
+ if !isUpperBound(E3.type, E2.type) {
+ raise type_error(E)
+ }
+ E.type = listof(E1.type)
+}
+```
+
+$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$
+
+```
+func dictExpr(E) {
+ supk := sup([e.type for e in E.keys()]])
+ supv := sup([e.type for e in E.values()]])
+ E.type = dictof(supk, supv)
+}
+```
+
+$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$
+
+```
+func dictComp(E) {
+ if !typeEqual(E6.type, boolean) {
+ raise type_error(E)
+ }
+ if !isUpperBound(dictof(Any, Any), E5.type) {
+ raise type_error(E)
+ }
+ if !isUpperBound(E5.type, dictof(E3.type, E4.type)) {
+ raise type_error(E)
+ }
+ E.type = dictof(E1.type, E2.type)
+}
+```
+
+$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$
+
+```
+func dictExpr(E) {
+ supk := sup(Ek1, ..., Ekn)
+ supv = sup(Ev1, ..., Evn)
+ E.type = dictof(supk, supv)
+}
+```
+
+$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$
+
+```
+func structExpr(E) {
+ Struct = structof()
+ for n, e in E {
+ Struct.add(n, e.type)
+ }
+ E.type = Struct
+}
+```
+
+#### Primary Expr
+
+$E \to E_1[E_2]$
+
+```
+func sliceSuffix(E) {
+ if !isUpperBound(listof(Any), E.E1.type) {
+ raise type_error(E)
+ }
+ if typeEqual(E.E2.type, integer) {
+ raise type_error(E)
+ }
+ E.type = E.E1.type.eleType
+}
+```
+
+$E \to E_1(E_2)$
+
+```
+func callSuffix(E) {
+ if !typeEqual(E.E1.type, func) {
+ raise type_error(E)
+ }
+ if !isUpperBound(listof(E.E1.arguType), E.E2.type) {
+ raise type_error(E)
+ }
+ E.type = E.E1.returnType
+}
+```
+
+#### Unary Expr
+
+根据每条双目运算符的推理规则推导,以 '+' 为例
+
+$E \to + E_1$
+
+```
+func Plus(E) {
+ if !typeEqual(E.E1.type, [integer, float]) {
+ raise type_error(E)
+ }
+ E.type = E.E1.type
+}
+```
+
+#### Binary Expr
+
+根据每条双目运算符的推理规则推导,以 '%' 为例
+
+$E \to E_1 \ % \ E_2$
+
+```
+func Mod(E) {
+ if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) {
+ raise type_error(E)
+ }
+ E.type = E.E1.type
+}
+```
+
+#### IF Binary Expr
+
+$E \to if E_1 \ then \ E_2 else \ E_3$
+
+```
+func ifExpr(E) {
+ if !typeEqual(E.type, boolean) {
+ raise type_error(E)
+ }
+ if !typeEqual(E_2.type, E_3.type) {
+ raise type_error(E)
+ }
+ E.type = E_2.type
+}
+```
+
+#### Stmt
+
+$S \to if \ E \ then \ S_1 \ else \ S_2$
+
+```
+func ifStmt(S) {
+ if !typeEqual(S.E.type, boolean) {
+ raise type_error(E)
+ }
+ if !typeEqual(S.S1.type, S.S2.type) {
+ raise type_error(E)
+ }
+ S.type = S.S1.type
+}
+```
+
+$S \to id: T = E$
+
+$S \to id = T E$
+
+```
+func assignStmt(S) {
+ tpe := env.lookup(id.entry)
+ if tpe != nil && tpe != S.T {
+ raise type_error(E)
+ }
+ if isUpperBound(tpe, E.type) {
+ raise type_error(E)
+ }
+ env.addtype(id.entry, T.type)
+}
+```
+
+## 类型转换
+
+### 基础定义
+
+通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换
+
+### 转换规则
+
+$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$
+
+```
+func binOp(E) {
+ if E.E1.type == integer and E.E2.type == integer {
+ E.type = integer
+ } else if E.E1.type == integer and E.E2.type == float {
+ E.type = float
+ } else if E.E1.type == float and E.E2.type == integer {
+ E.type = float
+ } else if E.E1.type == float and E.E2.type == float {
+ E.type = float
+ }
+}
+```
+
+## 类型推导
+
+### 基础定义
+
+- 在类型信息不完全的情况下类型规则推导、重建类型
+- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct
+
+### 基础方法
+
+1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合
+2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。
+
+### 推导逻辑
+
+$E \to id = E_1$
+
+```
+func assignExpr(E, subst) {
+ return unifier(E.id.type, E.E_1.type, subst, E)
+}
+```
+
+$unifier(t1, t2, subst, expr) \rightarrow subst$
+
+```
+func unifier(t1, t2, subst, expr) {
+ t1 = applySubstToTypeEquation(t1, subst)
+ t2 = applySubstToTypeEquation(t2, subst)
+
+ if t1 == t2 {
+ return subst
+ }
+
+ if isTypeVar(t1) {
+ if isNoOccur(t1, t2) {
+ addTypeEquationToSubst(subst, t1, t2)
+ return subst
+ } else {
+ raise occurrence_violation_error(t1, t2, expr)
+ }
+ }
+
+ if isTypeVar(t2) {
+ if isNoOccur(t2, t1) {
+ addTypeEquationToSubst(subst, t2, t1)
+ return subst
+ } else {
+ raise occurrence_violation_error(t2, t1, expr)
+ }
+ }
+
+ if isList(t1) and isList(t2) {
+ return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr)
+ }
+ if isDict(t1) and isDict(t2) {
+ dict1of := toDictOf(t1)
+ dict2of := toDictOf(t2)
+ subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr)
+ subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr)
+ return subst
+ }
+ if isStruct(t1) and isStruct(t2) {
+ Struct1of := tostructof(t1)
+ Struct2of := tostructof(t2)
+ for key, _ in Struct1of {
+ subst = unifier(t1[key].type, t2[key].type, subst, expr)
+ }
+ return subst
+ }
+
+ raise unification_error(t1, t2, expr)
+}
+
+func applySubstToTypeEquation(t, subst) {
+ // walks through the type t, replacing each type variable by its binding in the substitution
+σ. If a variable is Not bound in the substitution, then it is left unchanged.
+ if isBasicType(t) {
+ return t
+ }
+ if isList(t) {
+ return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst))
+ }
+ if isDict(t) {
+ dictof := toDictOf(t)
+ kT := applySubstToTypeEquation(dictof.keyType, subst)
+ vT := applySubstToTypeEquation(dictof.valueType, subst)
+ return dictOf(kT, vT)
+ }
+ if isStruct(t) {
+ structof := tostructof(t)
+ s := structof()
+ for key, type in Struct1of {
+ kT := applySubstToTypeEquation(type, subst)
+ s.add(key, kT)
+ }
+ return s
+ }
+ if hasTypeVar(t) {
+ for tvar in t.vars {
+ if tvar in subst {
+ *tvar = subst[tvar]
+ }
+ }
+ }
+ return t
+}
+
+func addTypeEquationToSubst(subst, tvar, t) {
+ // takes the substitution σ and adds the equation tv = t to it
+ for _, t in subst {
+ for tvar in t.vars {
+ tmp := applyOneSubst(tsvar, tvar, t)
+ *tvar = tmp
+ }
+ }
+ subst.add(tvar, t)
+}
+
+func applyOneSubst(t0, tvar, t1) {
+ // substituting t1 for every occurrence of tv in t0.
+ if isBasicType(t0) {
+ return t0
+ }
+ if isList(t0) {
+ return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1))
+ }
+ if isDict(t0) {
+ dictof := toDictOf(t)
+ kT := applyOneSubst(dictof.keyType, tvar, t1)
+ vT := applyOneSubst(dictof.valueType, tvar, t1)
+ return dictOf(kT, vT)
+ }
+ if isStruct(t0) {
+ structof := tostructof(t)
+ s := structof()
+ for key, type in Struct1of {
+ kT := applyOneSubst(type, tvar, t1)
+ s.add(key, kT)
+ }
+ return s
+ }
+ if t0 == tvar {
+ return t1
+ }
+ return t0
+}
+
+func isNoOccur(tvar, t) {
+ // No variable bound in the substitution occurs in any of the right-hand sides of the substitution.
+ if isBasicType(t) {
+ return true
+ }
+ if isList(t) {
+ return isNoOccur(tvar, toListOf(t).eleType)
+ }
+ if isDict(t) {
+ dictof := toDictOf(t)
+ return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType)
+ }
+ if isStruct(t) {
+ structof := tostructof(t)
+ noOccur := true
+ for _, type in structof {
+ noOccur = noOccur and isNoOccur(tvar, type)
+ }
+ return noOccur
+ }
+ return tvar != t
+}
+```
+
+### 示例
+
+#### 正常推导
+
+```
+T : {
+ a = 1
+ b = "2"
+ c = a * 2
+ d = {
+ d0 = [a, c]
+ }
+}
+
+x: T = {
+ a = 10
+}
+```
+
+#### Occurrence Violation Error
+
+```
+T = {
+ a = a
+}
+```
+
+#### Type Unification Error
+
+```
+T : {
+ a = 1
+}
+
+T : {
+ a = "1"
+}
+```
+
+## Reference
+
+- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system)
+- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press.
+- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/)
+- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html)
+- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html)
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/_category_.json
new file mode 100644
index 000000000..53e27fd40
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "模块系统",
+ "position": 2
+}
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/base64.md
new file mode 100644
index 000000000..71d70481a
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/base64.md
@@ -0,0 +1,31 @@
+---
+title: "base64"
+linkTitle: "base64"
+type: "docs"
+description: base64 编码解码
+weight: 100
+---
+
+## encode
+
+`encode(value: str, encoding: str = "utf-8") -> str`
+
+使用注册的编码器对字符串 `value` 进行编码。
+
+```python
+import base64
+
+abcd_base64 = base64.encode("abcd")
+```
+
+## decode
+
+`decode(value: str) -> str`
+
+使用注册的编码器对字符串 `value` 进行解码,解码的结果是一个 utf8 字符串
+
+```python
+import base64
+
+decode = base64.decode("MC4zLjA=")
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/builtin.md
new file mode 100644
index 000000000..46d2f18b3
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/builtin.md
@@ -0,0 +1,415 @@
+---
+title: "builtin"
+sidebar_position: 1
+---
+
+KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。
+
+## 类型转换函数
+
+KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。
+
+下面是类型相关函数常见的用法:
+
+```py
+b1 = bool(1) # true
+b2 = bool(1.5) # true
+b3 = bool("true") # true
+b4 = bool("") # false
+b5 = bool([]) # false
+b6 = bool({}) # false
+
+i1 = int("11") # 11
+i2 = int("11", base=8) # 9
+i3 = int("11", base=2) # 3
+
+f1 = float(1) # 1.0
+f2 = float("1.5") # 1.5
+
+s1 = str(1) # 1
+
+l1 = list([1, 2, 3])
+```
+
+## String 类型成员函数
+
+参考 [String 文档](/docs/reference/lang/spec/datatypes)
+
+## print
+
+`print(*args:any, end:str='\n')`
+
+内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法:
+
+```python
+print("hello KCL")
+print()
+print(None, end=':')
+print(None)
+print(True)
+print(False)
+print(123)
+print(123.0)
+print('abc ${123}')
+print("abc ${456}")
+print([1,'a', True])
+print(1,'a', True)
+print({})
+print({a: 123})
+```
+
+输出格式如下:
+
+```shell
+hello KCL
+
+None:None
+True
+False
+123
+123.0
+abc 123
+abc 456
+[1, 'a', True]
+1 a True
+{}
+{'a': 123}
+```
+
+如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。
+
+## multiplyof
+
+`multiplyof(a:int, b:int) -> bool`
+
+判断整数 `a` 是否为 `b` 的整数倍,返回布尔值:
+
+```python
+print(multiplyof(2, 1)) # True
+print(multiplyof(1, 2)) # False
+print(multiplyof(0, 1)) # True
+print(multiplyof(0, 2)) # True
+print(multiplyof(1, 0)) # Error
+```
+
+`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。
+
+## isunique
+
+`isunique(list: [any]) -> bool`
+
+判断数组中是否存在重复的元素,返回布尔值:
+
+```python
+print(isunique([])) # True
+print(isunique([1])) # True
+print(isunique([1, 2])) # True
+
+print(isunique([1, 1])) # False
+print(isunique([1, 1.0])) # False
+print(isunique([1.1, 1.1])) # False
+
+print(isunique(['abc', "abc"])) # False
+print(isunique(['abc', "a${'bc'}"])) # False
+```
+
+## isnullish
+
+如果输入值是 `None` 或 `Undefined`,则返回 `True`;否则返回 `False`。
+
+```python
+isnullish(None) # True
+isnullish(Undefined) # True
+isnullish(0) # False
+isnullish([]) # False
+isnullish({}) # False
+isnullish([None]) # False
+isnullish([Undefined]) # False
+```
+
+需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。
+
+## len
+
+`len(x: str | [any] | {:}) -> int`
+
+返回字符串、列表和数组的长度:
+
+```python
+print(len([])) # 0
+print(len({})) # 0
+
+print(len([1])) # 1
+print(len({abc:123})) # 1
+
+print("abc") # 3
+```
+
+注:不支持对 `schema` 对象计算长度。
+
+## abs
+
+`abs(x: number) -> number`
+
+计算 `x` 的绝对值。
+
+## all_true
+
+`all_true(x:str|[]|{:}) -> bool`
+
+判断列表或字典类全部元素为真,用法如下:
+
+```python
+print(all_true([])) # True
+print(all_true({})) # True
+
+print(all_true([True])) # True
+print(all_true([1])) # True
+
+print(all_true([True, False])) # False
+print(all_true([True, None])) # False
+```
+
+当列表为空时返回真。
+
+
+
+## any_true
+
+`any_true(x:str|[]|{:}) -> bool`
+
+判断可迭代对象中至少有一个元素为真,用法如下:
+
+```python
+print(any_true([])) # False
+print(any_true([1])) # True
+```
+
+## bin
+
+`bin(x:number) -> str`
+
+返回整数的二进制表示的字符串,用法如下:
+
+```python
+print(bin(8)) # 0b1000
+```
+
+## hex
+
+`hex(number)`
+
+返回整数的十六进制表示的字符串,用法如下:
+
+```python
+print(hex(18)) # 0x12
+```
+
+## oct
+
+`oct(number)`
+
+返回整数的八进制表示的字符串,用法如下:
+
+```python
+print(oct(10)) # 0o12
+```
+
+## option
+
+`option(key:str, type:str='', required=False, default=None, help="") -> any`
+
+获取命令行参数输入的值。
+
+## ord
+
+`ord(c) -> int`
+
+获取字符的 Unicode 码点值,用法如下:
+
+```python
+print(ord('A')) # 65
+print(ord('B')) # 66
+print(ord('C')) # 67
+```
+
+## sorted
+
+`sorted(x: []) -> []`
+
+返回排序后的列表,用法如下:
+
+```python
+_a = []
+_b = [2, 1]
+
+_c = sorted(_a)
+_d = sorted(_b)
+
+print(_a) # []
+print(_b) # [2, 1]
+print(_c) # []
+print(_d) # [1, 2]
+```
+
+## range
+
+`range(start:int, end:int, step=1) -> [int]`
+
+产生迭代列表,用法如下:
+
+```python
+print(range(1,5)) # [1, 2, 3, 4]
+print(range(1,5, 2)) # [1, 3]
+print(range(5, 1, -1)) # [5, 4, 3, 2]
+```
+
+## min
+
+`min(x:[number]) -> number`
+
+返回列表中最小的元素,用法如下:
+
+```python
+print(min([1,2])) # 1
+print(min([2,1])) # 1
+```
+
+
+
+## max
+
+`max(x:[number]) -> number`
+
+返回列表中最大的元素,用法如下:
+
+```python
+print(max([1,2])) # 2
+print(max([2,1])) # 2
+```
+
+## sum
+
+`sum(x:[number], init_value=0) -> number`
+
+返回列表中全部元素的和,用法如下:
+
+```
+print(sum([1,2])) # 3
+print(sum([2,1], 1000)) # 1003
+```
+
+## pow
+
+`pow(x: number, y: number, z: number = None) -> number`
+
+计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。
+
+下面的常见的用法:
+
+```python
+print(pow(2,3)) # 8
+print(pow(2, 3, 5)) # 8%5 == 3
+
+print(pow(2, 0.5)) # 1.414
+```
+
+## round
+
+`round(number: int|float, ndigits:int|None) -> float | int`
+
+返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。
+
+下面是常用的用法:
+
+```python
+print(round(1)) # 1
+print(round(1.4)) # 1
+print(round(1.5)) # 2
+
+print(round(1.5555, 1)) # 1.6
+print(round(1.5555, 2)) # 1.56
+
+print(round(1.5555)) # 2
+print(round(1.5555, 0)) # 2.0
+```
+
+需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。
+
+## typeof
+
+`typeof(x: any, full_name: bool = False) -> str`
+
+输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。
+
+下面是常见的用法:
+
+```python
+import sub as pkg
+
+_a = 1
+
+t1 = typeof(_a)
+t2 = typeof("abc")
+
+schema Person:
+ name?: any
+
+_x1 = Person{}
+t3 = typeof(_x1)
+
+_x2 = pkg.Person{}
+t4 = typeof(_x2)
+t5 = typeof(_x2, full_name=True)
+
+t6 = typeof(_x1, full_name=True)
+
+# 输出
+# t1: int
+# t2: str
+# t3: Person
+# t4: Person
+# t5: sub.Person
+# t6: __main__.Person
+```
+
+## zip
+
+`zip(*args: str|list|dict)`
+
+用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
+
+下面是常见的用法:
+
+```py
+a = zip([0, 1, 2], [3, 4, 5])
+b = zip([0, 1], [3, 4, 5])
+c = zip([0, 1, 2], [3, 4, 5, 6])
+
+# 输出
+# a:
+# - - 0
+# - 3
+# - - 1
+# - 4
+# - - 2
+# - 5
+# b:
+# - - 0
+# - 3
+# - - 1
+# - 4
+# c:
+# - - 0
+# - 3
+# - - 1
+# - 4
+# - - 2
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/crypto.md
new file mode 100644
index 000000000..ffde99dc7
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/crypto.md
@@ -0,0 +1,139 @@
+---
+title: "crypto"
+linkTitle: "crypto"
+type: "docs"
+description: crypto 包 - 提供 SHA 相关的哈希函数
+weight: 100
+---
+
+## md5
+
+`md5(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+md5 = crypto.md5("ABCDEF")
+```
+
+## sha1
+
+`sha1(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+sha = crypto.sha1("ABCDEF")
+```
+
+## sha224
+
+`sha224(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+sha = crypto.sha224("ABCDEF")
+```
+
+## sha256
+
+`sha256(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+sha = crypto.sha256("ABCDEF")
+```
+
+## sha384
+
+`sha384(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+sha = crypto.sha384("ABCDEF")
+```
+
+## sha512
+
+`sha512(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+sha = crypto.sha512("ABCDEF")
+```
+
+## blake3
+
+`sha512(value: str, encoding: str = "utf-8") -> str`
+
+使用注册编码器和 `BLAKE3` 算法对字符串 `value` 进行加密。
+
+```python
+import crypto
+
+blake3 = crypto.blake3("ABCDEF")
+```
+
+## fileblake3
+
+`fileblake3(filepath: str) -> str`
+
+使用注册编码器和 `BLAKE3` 算法对从文件`filepath`读取出的内容进行加密。
+
+```python
+import crypto
+
+fileblake3 = crypto.fileblake3("test.txt")
+```
+
+## uuid
+
+`uuid() -> str`
+
+生成一个随机 UUID 字符串。
+
+```python
+import crypto
+
+a = crypto.uuid()
+```
+
+## filesha256
+
+`filesha256(filepath: str) -> str`
+
+计算文件 `filepath` 的 SHA256 哈希。
+
+```python
+import crypto
+
+sha = crypto.filesha256("test.txt")
+```
+
+## filesha512
+
+`filesha512(filepath: str) -> str`
+
+计算文件 `filepath` 的 SHA512 哈希。
+
+```python
+import crypto
+
+sha = crypto.filesha512("test.txt")
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/datetime.md
new file mode 100644
index 000000000..fae58f413
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/datetime.md
@@ -0,0 +1,67 @@
+---
+title: "datetime"
+linkTitle: "datetime"
+type: "docs"
+description: datetime 包 - 时间处理
+weight: 100
+---
+
+## ticks
+
+`ticks() -> float`
+
+返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。
+
+```python
+import datetime
+
+ticks = datetime.ticks()
+```
+
+## date
+
+`date() -> str`
+
+返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。
+
+```python
+import datetime
+
+date = datetime.date()
+```
+
+## now
+
+`now(format: str = "%a %b %d %H:%M:%S %Y") -> str`
+
+返回本地时间格式。例如:`Sat Jun 06 16:26:11 1998`,或者根据指定的格式字符串格式化组合的日期和时间,默认日期格式为 `%a %b %d %H:%M:%S %Y`。
+
+```python
+import datetime
+
+date = datetime.now()
+```
+
+## today
+
+`today() -> str`
+
+返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。
+
+```python
+import datetime
+
+date = datetime.today()
+```
+
+## validate
+
+`validate(date: str, format: str) -> bool`
+
+验证提供的日期字符串是否与指定格式匹配。
+
+```python
+import datetime
+
+result = datetime.validate("2024-08-26", "%Y-%m-%d") # Valid date
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/file.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/file.md
new file mode 100644
index 000000000..c194becfa
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/file.md
@@ -0,0 +1,175 @@
+---
+title: "file"
+linkTitle: "file"
+type: "docs"
+description: 文件系统操作
+weight: 100
+---
+
+## read
+
+`read(filepath: str) -> str`
+
+读取文件 `filepath` 中的内容,并返回一个字符串实例。
+
+```python
+import file
+
+a = file.read("test.txt")
+```
+
+## glob
+
+`glob(pattern: str) -> str`
+
+返回一个包含所有匹配 `pattern` 的文件名的列表。
+
+```python
+import file
+
+json_files = file.glob("./*.json")
+```
+
+## modpath
+
+`modpath() -> str`
+
+返回当前模块的根路径(kcl.mod 文件路径或单个 \*.k 文件路径)。
+
+```python
+import file
+
+modpath = file.modpath()
+```
+
+## workdir
+
+`workdir() -> str`
+
+返回当前工作目录的路径。
+
+```python
+import file
+
+workdir = file.workdir()
+```
+
+## exists
+
+`exists(filepath: str) -> bool`
+
+判断文件路径是否存在。如果路径指向一个存在的实体,则返回 True。此函数会遍历符号链接以查询目标文件的信息。
+
+```python
+import file
+
+file_exists = file.exists("test.txt")
+```
+
+## abs
+
+`abs(filepath: str) -> str`
+
+返回路径的规范化绝对形式,其中所有中间路径均已规范化并解析为符号链接。
+
+```python
+import file
+
+abs_file_path = file.abs("test.txt")
+```
+
+## mkdir
+
+`mkdir(directory: str, exists: bool=False)`
+
+如果指定路径上不存在目录,则创建一个新目录。
+
+```python
+import file
+
+file.mkdir("path")
+```
+
+## delete
+
+`delete(directory: str)`
+
+在指定路径上删除一个文件或空目录。
+
+```python
+import file
+
+file.delete("test.txt")
+```
+
+## cp
+
+`cp(src: str, dest: str)`
+
+将文件或目录从源路径复制到目标路径。
+
+```python
+import file
+
+file.cp("src", "dest")
+```
+
+## mv
+
+`mv(src: str, dest: str)`
+
+将文件或目录从源路径移动到目标路径。
+
+```python
+import file
+
+file.mv("src", "dest")
+```
+
+## size
+
+`size(filepath: str) -> int`
+
+获取指定路径上文件的大小。
+
+```python
+import file
+
+size = file.size("test.txt")
+```
+
+## write
+
+`write(filepath: str, content: str)`
+
+将内容写入指定路径的文件。如果文件不存在,将会被创建。如果文件存在,其内容将被替换。
+
+```python
+import file
+
+file.size("test.txt", "content")
+```
+
+## read_env
+
+`read_env(key: str) -> str`
+
+从当前进程中读取环境变量 `key` 的值。
+
+```python
+import file
+
+value = file.read_env("ENV_VAR")
+```
+
+## current
+
+`current() -> str`
+
+读取正在执行的当前 KCL 代码文件或模块的路径。
+
+```python
+import file
+
+value = file.current()
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/json.md
new file mode 100644
index 000000000..da7a338ee
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/json.md
@@ -0,0 +1,111 @@
+---
+title: "json"
+linkTitle: "json"
+type: "docs"
+description: JSON 编码解码
+weight: 100
+---
+
+## encode
+
+```python
+encode(
+ data: any,
+ sort_keys: bool = False,
+ indent: int = None,
+ ignore_private: bool = False,
+ ignore_none: bool = False
+) -> str
+```
+
+将 KCL 对象 `data` 序列化为 JSON 格式的字符串。
+
+```python
+import json
+
+data = {
+ "key1": "value1"
+ "key2": "value2"
+ "data": [1, 2, 3]
+}
+data_string = json.encode(data)
+```
+
+## decode
+
+`decode(value: str) -> any`
+
+反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。
+
+```python
+import file
+import json
+
+data_string = json.decode(file.read(file.modpath()+"/test.json"))
+
+key1 = data_string.key1
+key2 = data_string.key2
+data = data_string.data
+```
+
+## dump_to_file
+
+```python
+dump_to_file(
+ data: any,
+ filename: str,
+ sort_keys: bool = False,
+ indent: int = None,
+ ignore_private: bool = False,
+ ignore_none: bool = False
+) -> None
+```
+
+将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。
+
+```python
+import json
+
+schema Person:
+ name?: str
+ age?: int
+ school?: str
+ data?: [int] = [1, 2, None]
+
+person = Person {
+ name: "Alice"
+ age: 18
+}
+filename = "out.json"
+json.dump_to_file(person, filename, indent=4, ignore_private=True, ignore_none=True)
+```
+
+## validate
+
+```python
+validate(value: str) -> bool
+```
+
+验证给定的字符串是否是一个合法的 JSON 字符串。
+
+```python
+import json
+
+# Right cases
+
+resultRight1: bool = json.validate("1")
+resultRight2: bool = json.validate("true")
+resultRight3: bool = json.validate("1.20")
+resultRight4: bool = json.validate("null")
+resultRight5: bool = json.validate("[0, 1, 2]")
+resultRight6: bool = json.validate('{"key": "value"}')
+
+# Wrong cases
+
+resultWrong1: bool = json.validate("1@")
+resultWrong2: bool = json.validate("True")
+resultWrong3: bool = json.validate("1.20.23+1")
+resultWrong4: bool = json.validate("None")
+resultWrong5: bool = json.validate("[0, 1, 2,]")
+resultWrong6: bool = json.validate(r'''{"key": 'value'}''')
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/manifests.md
new file mode 100644
index 000000000..5c54e9c76
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/manifests.md
@@ -0,0 +1,89 @@
+---
+title: "manifests"
+linkTitle: "manifests"
+type: "docs"
+description: manifests system module
+weight: 100
+---
+
+## yaml_stream
+
+```python
+yaml_stream(values: [any], opts: {str:} = {
+ sort_keys = False
+ ignore_private = True
+ ignore_none = False
+ sep = "---"
+})
+```
+
+这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数:
+
+- `values` - 一个 KCL 对象列表
+- `opts` - YAML 序列化选项
+ - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。
+ - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。
+ - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。
+ - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。
+
+下面我们通过一个例子来说明:
+
+```python
+# 使用 `import` 关键词导入 `manifests` 模块
+import manifests
+
+# `Deployment` schema 定义
+schema Deployment:
+ apiVersion: str = "v1"
+ kind: str = "Deployment"
+ metadata: {str:} = {
+ name = "deploy"
+ }
+ spec: {str:} = {
+ replica = 2
+ }
+
+# `Service` schema 定义
+schema Service:
+ apiVersion: str = "v1"
+ kind: str = "Service"
+ metadata: {str:} = {
+ name = "svc"
+ }
+ spec: {str:} = {}
+
+# 定义两个 `Deployment` 资源
+deployments = [Deployment {}, Deployment {}]
+# 定义两个 `Service` 资源
+services = [Service {}, Service {}]
+# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。
+manifests.yaml_stream(deployments + services)
+```
+
+首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为:
+
+```yaml
+apiVersion: v1
+kind: Deployment
+metadata:
+ name: deploy
+spec:
+ replica: 2
+---
+apiVersion: v1
+kind: Deployment
+metadata:
+ name: deploy
+spec:
+ replica: 2
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: svc
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: svc
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/math.md
new file mode 100644
index 000000000..e16558b27
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/math.md
@@ -0,0 +1,216 @@
+---
+title: "math"
+linkTitle: "math"
+type: "docs"
+description: math 包 - 数学函数
+weight: 100
+---
+
+## ceil
+
+`ceil(x) -> int`
+
+返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。
+
+```python
+import math
+
+a = math.ceil(-45.17)
+b = math.ceil(100.12)
+```
+
+## factorial
+
+`factorial(x) -> int`
+
+返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。
+
+```python
+import math
+
+a = math.factorial(5)
+```
+
+## floor
+
+`floor(x) -> int`
+
+返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。
+
+```python
+import math
+
+a = math.floor(-45.17)
+b = math.floor(100.12)
+```
+
+## gcd
+
+`gcd(a: int, b: int) -> int`
+
+返回 `x` 和 `y` 的最大公约数。
+
+```python
+import math
+
+a = math.gcd(60, 48)
+```
+
+## isfinite
+
+`isfinite(x) -> bool`
+
+如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。
+
+```python
+import math
+
+a = math.isfinite(1)
+b = math.isfinite(0)
+c = math.isfinite(float("nan"))
+```
+
+## isinf
+
+`isinf(x) -> bool`
+
+如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。
+
+```python
+import math
+
+a = math.isinf(1)
+b = math.isinf(0)
+c = math.isinf(float("nan"))
+```
+
+## isnan
+
+`isnan(x) -> bool`
+
+如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。
+
+```python
+import math
+
+a = math.isnan(1)
+b = math.isnan(0)
+c = math.isnan(float("nan"))
+```
+
+## modf
+
+`modf(x) -> List[float, float]`
+
+返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。
+
+```python
+import math
+
+a = math.modf(100.12)
+b = math.modf(100.72)
+```
+
+## exp
+
+`exp(x) -> float`
+
+返回以 `e` 为底数, `x` 的幂。
+
+```python
+import math
+
+a = math.exp(2)
+b = math.exp(-6.89)
+```
+
+## expm1
+
+`expm1(x) -> float`
+
+返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。
+
+```python
+import math
+
+a = math.expm1(32)
+b = math.expm1(-10.89)
+```
+
+## log
+
+`log(x, base=2.71828182845904523536028747135266250) -> float`
+
+返回以 `e` 为底数,`x` 的对数。
+
+```python
+import math
+
+a = math.log10(100) # 2
+```
+
+## log1p
+
+`log1p(x) -> float`
+
+返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。
+
+```python
+import math
+
+a = math.log1p(2.7183)
+b = math.log1p(2)
+c = math.log1p(1)
+```
+
+## log2
+
+`log2(x) -> float`
+
+返回 `x` 的以 2 为底的对数。
+
+```python
+import math
+
+a = math.log2(2.7183)
+b = math.log2(2)
+c = math.log2(1)
+```
+
+## log10
+
+`log10(x) -> float`
+
+返回 `x` 的以 10 为底的对数。
+
+```python
+import math
+
+a = math.log10(2.7183)
+b = math.log10(2)
+c = math.log10(1)
+```
+
+## pow
+
+`pow(x, y) -> float`
+
+返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。
+
+```python
+import math
+
+a = math.pow(1, 1)
+```
+
+## sqrt
+
+`sqrt(x) -> float`
+
+返回 `x` 的平方根。
+
+```python
+import math
+
+a = math.sqrt(9)
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/net.md
new file mode 100644
index 000000000..607466db5
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/net.md
@@ -0,0 +1,201 @@
+---
+title: "net"
+linkTitle: "net"
+type: "docs"
+description: net 包 - 网络IP处理
+weight: 100
+---
+
+## split_host_port
+
+`split_host_port(ip_end_point: str) -> List[str]`
+
+从 `ip_end_point` 分离出 `host` 和 `port`。
+
+```python
+import net
+
+host_and_port = net.split_host_port("B-K0NZJGH6-0048.local:80")
+host_port = net.join_host_port("B-K0NZJGH6-0048.local", 80)
+```
+
+## join_host_port
+
+`join_host_port(host, port) -> str`
+
+合并 `host` 和 `port`。
+
+```python
+import net
+
+host_and_port = net.split_host_port("B-K0NZJGH6-0048.local:80")
+host_port = net.join_host_port("B-K0NZJGH6-0048.local", 80)
+```
+
+## fqdn
+
+`fqdn(name: str = '') -> str`
+
+返回完全限定域名(FQDN)。
+
+```python
+import net
+
+fqdn = net.fqdn()
+```
+
+## parse_IP
+
+`parse_IP(ip) -> str`
+
+将 `ip` 解析为真实的 IP 地址。
+
+```python
+import net
+
+ip = net.parse_IP("192.168.0.1")
+```
+
+## to_IP4
+
+`to_IP4(ip) -> str`
+
+获取 `ip` 的 IPv4 表示形式。
+
+```python
+import net
+
+ip = net.to_IP4("192.168.0.1")
+```
+
+## to_IP16
+
+`to_IP16(ip) -> int`
+
+获取 `ip` 的 IPv6 表示形式。
+
+```python
+import net
+
+ip = net.to_IP16("192.168.0.1")
+```
+
+## IP_string
+
+`IP_string(ip: str | int) -> str`
+
+返回 IP 字符串。
+
+```python
+import net
+
+ip = net.IP_string("192.168.0.1")
+```
+
+## is_IPv4
+
+`is_IPv4(ip: str) -> bool`
+
+判断 `ip` 是否为 IPv4。
+
+```python
+import net
+
+ip = net.is_IPv4("192.168.0.1")
+```
+
+## is_IP
+
+`is_IP(ip: str) -> bool`
+
+判断 `ip` 是否为有效的 IP 地址。
+
+```python
+import net
+
+ip = net.is_IP("192.168.0.1")
+```
+
+## is_loopback_IP
+
+`is_loopback_IP(ip: str) -> bool`
+
+判断 `ip` 是否为回环地址。
+
+```python
+import net
+
+isip = net.is_loopback_IP("127.0.0.1")
+```
+
+## is_multicast_IP
+
+`is_multicast_IP(ip: str) -> bool`
+
+判断 `ip` 是否为组播地址。
+
+```python
+import net
+
+isip = net.is_multicast_IP("239.255.255.255")
+```
+
+## is_interface_local_multicast_IP
+
+`is_interface_local_multicast_IP(ip: str) -> bool`
+
+判断 `ip` 是否为接口、本地和组播地址。
+
+```python
+import net
+
+isip = net.is_interface_local_multicast_IP("239.255.255.255")
+```
+
+## is_link_local_multicast_IP
+
+`is_link_local_multicast_IP(ip: str) -> bool`
+
+判断 `ip` 是否为链路本地和组播地址。
+
+```python
+import net
+
+isip = net.is_link_local_multicast_IP("224.0.0.0")
+```
+
+## is_link_local_unicast_IP
+
+`is_link_local_unicast_IP(ip: str) -> bool`
+
+判断 `ip` 是否为链路本地和单播地址。
+
+```python
+import net
+
+isip = net.is_link_local_unicast_IP("fe80::2012:1")
+```
+
+## is_global_unicast_IP
+
+`is_global_unicast_IP(ip: str) -> bool`
+
+判断 `ip` 是否为全局单播地址。
+
+```python
+import net
+
+isip = net.is_global_unicast_IP("220.181.108.89")
+```
+
+## is_unspecified_IP
+
+`is_unspecified_IP(ip: str) -> bool`
+
+判断 `ip` 是否为 `unspecified` 地址。
+
+```python
+import net
+
+isip = net.is_unspecified_IP("0.0.0.0")
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/overview.md
new file mode 100644
index 000000000..129802224
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/model/overview.md
@@ -0,0 +1,63 @@
+---
+sidebar_position: 0
+---
+
+import DocsCard from '@site/src/components/global/DocsCard';
+import DocsCards from '@site/src/components/global/DocsCards';
+
+# 概览
+
+KCL 通过内置模块、系统库模块和插件模块提供工程化的扩展能力。
+
+
+
+用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。
+
+对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。
+
+## 系统库模块
+
+
+
+
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/cpp-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/cpp-api.md
new file mode 100644
index 000000000..f6235eabd
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/cpp-api.md
@@ -0,0 +1,628 @@
+---
+sidebar_position: 11
+---
+
+# C++ API
+
+The [C++ API](https://github.com/kcl-lang/lib/tree/main/cpp) is in the development stage and contributions are welcome.
+
+## Prerequisites
+
+- CMake >= 3.10
+- C++ Compiler with C++17 Support
+- Cargo
+
+## Installation
+
+### CMake
+
+You can use FetchContent to add KCL C++ Lib to your project.
+
+```shell
+FetchContent_Declare(
+ kcl-lib
+ GIT_REPOSITORY https://github.com/kcl-lang/lib.git
+ GIT_TAG v0.12.1 # You can change the GitHub branch tag.
+ SOURCE_SUBDIR cpp
+)
+FetchContent_MakeAvailable(kcl-lib)
+```
+
+Or you can download the source code and add it to your project.
+
+```shell
+mkdir third_party
+cd third_party
+git clone https://github.com/kcl-lang/lib.git
+```
+
+Update your CMake files.
+
+```shell
+add_subdirectory(third_party/lib/cpp)
+```
+
+```shell
+target_link_libraries(your_target kcl-lib-cpp)
+```
+
+## API Reference
+
+### exec_program
+
+Execute KCL file with arguments and return the JSON/YAML result.
+
+Example
+
+
+
+### load_package
+
+load_package provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+
+### override_file
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+
+### rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+
+### rename_code
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+
+### update_dependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/dotnet-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/dotnet-api.md
new file mode 100644
index 000000000..de3bef296
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/dotnet-api.md
@@ -0,0 +1,614 @@
+---
+sidebar_position: 5
+---
+
+# .NET API
+
+## Installation
+
+```shell
+dotnet add package KclLib
+```
+
+## Quick Start
+
+```typescript
+using KclLib.API;
+
+var api = new API();
+var execArgs = new ExecProgramArgs();
+var path = Path.Combine("test_data", "schema.k");
+execArgs.KFilenameList.Add(path);
+var result = api.ExecProgram(execArgs);
+Console.WriteLine(result.YamlResult);
+```
+
+## API Reference
+
+### ExecProgram
+
+Execute KCL file with arguments and return the JSON/YAML result.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var execArgs = new ExecProgramArgs();
+var path = "schema.k"
+execArgs.KFilenameList.Add(path);
+var result = new API().ExecProgram(execArgs);
+```
+
+
+
+
+### ParseFile
+
+Parse KCL single file to Module AST JSON string with import dependencies and parse errors.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "schema.k"
+var args = new ParseFileArgs { Path = path };
+var result = new API().ParseFile(args);
+```
+
+
+
+
+### ParseProgram
+
+Parse KCL program with entry files and return the AST JSON string.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "schema.k";
+var args = new ParseProgramArgs();
+args.Paths.Add(path);
+var result = new API().ListOptions(args);
+```
+
+
+
+
+### LoadPackage
+
+LoadPackage provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "schema.k";
+var args = new LoadPackageArgs();
+args.ResolveAst = true;
+args.ParseArgs = new ParseProgramArgs();
+args.ParseArgs.Paths.Add(path);
+var result = new API().LoadPackage(args);
+```
+
+
+
+
+### ListVariables
+
+ListVariables provides users with the ability to parse KCL program and get all variables by specs.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var api = new API();
+var args = new ListVariablesArgs();
+var path = "schema.k";
+args.Files.Add(path);
+var result = api.ListVariables(args);
+```
+
+
+
+
+### ListOptions
+
+ListOptions provides users with the ability to parse KCL program and get all option information.
+
+Example
+
+
+The content of `options.k` is
+
+```python
+a = option("key1")
+b = option("key2", required=True)
+c = {
+ metadata.key = option("metadata-key")
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "options.k";
+var args = new ParseProgramArgs();
+args.Paths.Add(path);
+var result = new API().ListOptions(args);
+```
+
+
+
+
+### GetSchemaTypeMapping
+
+Get schema type mapping defined in the program.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "schema.k";
+var execArgs = new ExecProgramArgs();
+execArgs.KFilenameList.Add(path);
+var args = new GetSchemaTypeMappingArgs();
+args.ExecArgs = execArgs;
+var result = new API().GetSchemaTypeMapping(args);
+```
+
+
+
+
+### OverrideFile
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+
+### FormatPath
+
+Format KCL file or directory path contains KCL files and returns the changed file paths.
+
+Example
+
+
+The content of `format_path.k` is
+
+```python
+schema Person:
+ name: str
+ age: int
+
+ check:
+ 0 < age < 120
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var api = new API();
+var args = new FormatPathArgs();
+var path = "format_path.k";
+args.Path = path;
+var result = api.FormatPath(args);
+```
+
+
+
+
+### LintPath
+
+Lint files and return error messages including errors and warnings.
+
+Example
+
+
+The content of `lint_path.k` is
+
+```python
+import math
+
+a = 1
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var path = "lint_path.k"
+var args = new LintPathArgs();
+args.Paths.Add(path);
+var result = new API().LintPath(args);
+bool foundWarning = result.Results.Any(warning => warning.Contains("Module 'math' imported but unused"));
+```
+
+
+
+
+### ValidateCode
+
+Validate code using schema and JSON/YAML data strings.
+
+Example
+
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+string code = @"
+schema Person:
+ name: str
+ age: int
+ check:
+ 0 < age < 120
+";
+string data = "{\"name\": \"Alice\", \"age\": 10}";
+var args = new ValidateCodeArgs
+{
+ Code = code,
+ Data = data,
+ Format = "json"
+};
+var result = new API().ValidateCode(args);
+```
+
+
+
+
+### Rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+b = a
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+RenameArgs args = RenameArgs.newBuilder().setPackageRoot(".").setSymbolPath("a")
+ .addFilePaths("main.k").setNewName("a2").build();
+API apiInstance = new API();
+RenameResult result = apiInstance.rename(args);
+```
+
+
+
+
+### RenameCode
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+
+### Test
+
+Test KCL packages with test arguments.
+
+Example
+
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var pkg = Path.Combine(parentDirectory, "test_data", "testing");
+var args = new TestArgs();
+args.PkgList.Add(pkg + "/...");
+var result = new API().Test(args);
+```
+
+
+
+
+### LoadSettingsFiles
+
+Load the setting file config defined in `kcl.yaml`
+
+Example
+
+
+The content of `kcl.yaml` is
+
+```yaml
+kcl_cli_configs:
+ strict_range_check: true
+kcl_options:
+ - key: key
+ value: value
+```
+
+C# Code
+
+```csharp
+using KclLib.API;
+
+var workDir = ".";
+var settingsFile = "kcl.yaml";
+var args = new LoadSettingsFilesArgs
+{
+ WorkDir = workDir,
+};
+args.Files.Add(settingsFile);
+var result = new API().LoadSettingsFiles(args);
+```
+
+
+
+
+### UpdateDependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
+
+## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L168)
+
+```go
+func FormatPath(path string) (changedPaths []string, err error)
+```
+
+FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively
+
+the returned changedPaths are the changed file paths \(relative path\)
+
+Example
+
+
+
+## func [GetSchemaTypeMapping](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L247)
+
+```go
+func GetSchemaTypeMapping(filename string, src any, schemaName string) (map[string]*KclType, error)
+```
+
+GetSchemaTypeMapping returns a \:\ mapping of schema types from a kcl file or code.
+
+file: string
+
+```
+The kcl filename
+```
+
+code: string
+
+```
+The kcl code string
+```
+
+schema_name: string
+
+```
+The schema name got, when the schema name is empty, all schemas are returned.
+```
+
+
+## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L188)
+
+```go
+func LintPath(paths []string) (results []string, err error)
+```
+
+LintPath lint files from the given path
+
+Example
+
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ kcl "kcl-lang.io/kcl-go"
+)
+
+func main() {
+ // import a
+ // import a # reimport
+
+ results, err := kcl.LintPath([]string{"testdata/lint/import.k"})
+ if err != nil {
+ log.Fatal(err)
+ }
+ for _, s := range results {
+ fmt.Println(s)
+ }
+
+}
+```
+
+```
+Module 'a' is reimported multiple times
+Module 'a' imported but unused
+Module 'a' imported but unused
+```
+
+
+
+
+## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L173)
+
+```go
+func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error)
+```
+
+ListDepFiles return the depend files from the given path
+
+## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L183)
+
+```go
+func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error)
+```
+
+ListDownStreamFiles return a list of downstream depend files from the given changed path list.
+
+## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L178)
+
+```go
+func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error)
+```
+
+ListUpStreamFiles return a list of upstream depend files from the given path list
+
+## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L197)
+
+```go
+func OverrideFile(file string, specs, importPaths []string) (bool, error)
+```
+
+OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. importPaths. List of import statements that need to be added. See https://www.kcl-lang.io/docs/user_docs/guides/automation for more override spec guide.
+
+## func [Validate](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L208)
+
+```go
+func Validate(dataFile, schemaFile string, opts *ValidateOptions) (ok bool, err error)
+```
+
+Validate validates the given data file against the specified schema file with the provided options.
+
+## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L202)
+
+```go
+func ValidateCode(data, code string, opts *ValidateOptions) (ok bool, err error)
+```
+
+ValidateCode validate data string match code string
+
+## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L56)
+
+```go
+type KCLResult = kcl.KCLResult
+```
+
+Example
+
+
+
+### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L79)
+
+```go
+func Run(path string, opts ...Option) (*KCLResultList, error)
+```
+
+Run evaluates the KCL program with path and opts, then returns the object list.
+
+### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L84)
+
+```go
+func RunFiles(paths []string, opts ...Option) (*KCLResultList, error)
+```
+
+RunFiles evaluates the KCL program with multi file path and opts, then returns the object list.
+
+Example
+
+
+
+## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L49)
+
+```go
+type Option = kcl.Option
+```
+
+### func [NewOption](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L89)
+
+```go
+func NewOption() *Option
+```
+
+NewOption returns a new Option.
+
+### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L94)
+
+```go
+func WithCode(codes ...string) Option
+```
+
+WithCode returns a Option which hold a kcl source code list.
+
+### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L123)
+
+```go
+func WithDisableNone(disableNone bool) Option
+```
+
+WithDisableNone returns a Option which hold a disable none switch.
+
+### func [WithExternalPkgAndPath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L100)
+
+```go
+func WithExternalPkgAndPath(name, path string) Option
+```
+
+WithExternalPkgAndPath returns a Option which hold a external package.
+
+### func [WithExternalPkgs](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L97)
+
+```go
+func WithExternalPkgs(externalPkgs ...string) Option
+```
+
+WithExternalPkgs returns a Option which hold a external package list.
+
+### func [WithFullTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L131)
+
+```go
+func WithFullTypePath(fullTypePath bool) Option
+```
+
+WithFullTypePath returns a Option which hold a include full type string in the \`\_type\` attribute.
+
+### func [WithIncludeSchemaTypePath](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L126)
+
+```go
+func WithIncludeSchemaTypePath(includeSchemaTypePath bool) Option
+```
+
+WithIncludeSchemaTypePath returns a Option which hold a include schema type path switch.
+
+### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L105)
+
+```go
+func WithKFilenames(filenames ...string) Option
+```
+
+WithKFilenames returns a Option which hold a filenames list.
+
+### func [WithLogger](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L151)
+
+```go
+func WithLogger(l io.Writer) Option
+```
+
+WithLogger returns a Option which hold a logger.
+
+### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L108)
+
+```go
+func WithOptions(key_value_list ...string) Option
+```
+
+WithOptions returns a Option which hold a key=value pair list for option function.
+
+Example
+
+
+
+## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L52)
+
+```go
+type ValidateOptions = validate.ValidateOptions
+```
+
+## type [VersionResult](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L60)
+
+```go
+type VersionResult = kcl.VersionResult
+```
+
+### func [GetVersion](https://github.com/kcl-lang/kcl-go/blob/main/kcl.go#L279)
+
+```go
+func GetVersion() (*VersionResult, error)
+```
+
+GetVersion returns the KCL service version information.
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/java-api.md
new file mode 100644
index 000000000..f7d24658a
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/java-api.md
@@ -0,0 +1,623 @@
+---
+sidebar_position: 5
+---
+
+# Java API
+
+## Installation
+
+Refer to [this](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages) to configure your Maven; set up your GitHub account and Token in the `settings.xml`.
+
+### Maven
+
+In your project's pom.xml, configure our repository as follows:
+
+```xml
+
+
+ github
+ https://maven.pkg.github.com/kcl-lang/*
+
+ true
+
+
+
+```
+
+This way you'll be able to import the above dependency to use the SDK.
+
+```xml
+
+ com.kcl
+ kcl-lib
+ 0.12.1
+
+```
+
+## Quick Start
+
+```java
+import com.kcl.api.API;
+import com.kcl.api.Spec.ExecProgramArgs;
+import com.kcl.api.Spec.ExecProgramResult;
+
+public class ExecProgramTest {
+ public static void main(String[] args) throws Exception {
+ API api = new API();
+ ExecProgramResult result = api
+ .execProgram(ExecProgramArgs.newBuilder().addKFilenameList("path/to/kcl.k").build());
+ System.out.println(result.getYamlResult());
+ }
+}
+```
+
+## API Reference
+
+### execProgram
+
+Execute KCL file with arguments and return the JSON/YAML result.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+ExecProgramArgs args = ExecProgramArgs.newBuilder().addKFilenameList("schema.k").build();
+API apiInstance = new API();
+ExecProgramResult result = apiInstance.execProgram(args);
+```
+
+
+
+
+### parseFile
+
+Parse KCL single file to Module AST JSON string with import dependencies and parse errors.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+ParseFileArgs args = ParseFileArgs.newBuilder().setPath("schema.k").build();
+API apiInstance = new API();
+ParseFileResult result = apiInstance.parseFile(args);
+```
+
+
+
+
+### parseProgram
+
+Parse KCL program with entry files and return the AST JSON string.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+import com.kcl.ast.*;
+import com.kcl.util.JsonUtil;
+
+API api = new API();
+ParseProgramResult result = api.parseProgram(
+ ParseProgramArgs.newBuilder().addPaths("path/to/kcl.k").build()
+);
+System.out.println(result.getAstJson());
+Program program = JsonUtil.deserializeProgram(result.getAstJson());
+```
+
+
+
+
+### loadPackage
+
+loadPackage provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+API api = new API();
+LoadPackageResult result = api.loadPackage(LoadPackageArgs.newBuilder().setResolveAst(true)
+ .setWithAstIndex(true)
+ .setParseArgs(ParseProgramArgs.newBuilder().addPaths("schema.k").build()).build());
+```
+
+
+
+
+### listVariables
+
+listVariables provides users with the ability to parse KCL program and get all variables by specs.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+API api = new API();
+ListVariablesResult result = api.listVariables(
+ ListVariablesArgs.newBuilder().setResolveAst(true).setParseArgs(
+ ParseProgramArgs.newBuilder().addPaths("/path/to/kcl.k").build())
+ .build());
+result.getSymbolsMap().values().forEach(s -> System.out.println(s));
+```
+
+
+
+
+### listOptions
+
+listOptions provides users with the ability to parse KCL program and get all option information.
+
+Example
+
+
+
+### overrideFile
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+
+b = {
+ "a": 1
+ "b": 2
+}
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+API api = new API();
+String spec = "a=2";
+OverrideFileResult result = api.overrideFile(OverrideFileArgs.newBuilder()
+ .setFile("./src/test_data/override_file/main.k").addSpecs(spec).build());
+```
+
+
+
+
+### rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+b = a
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+RenameArgs args = RenameArgs.newBuilder().setPackageRoot(".").setSymbolPath("a")
+ .addFilePaths("main.k").setNewName("a2").build();
+API apiInstance = new API();
+RenameResult result = apiInstance.rename(args);
+```
+
+
+
+
+### renameCode
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+API api = new API();
+RenameCodeArgs args = RenameCodeArgs.newBuilder().setPackageRoot("/mock/path").setSymbolPath("a")
+ .putSourceCodes("/mock/path/main.k", "a = 1\nb = a").setNewName("a2").build();
+RenameCodeResult result = api.renameCode(args);
+```
+
+
+
+
+### test
+
+Test KCL packages with test arguments.
+
+Example
+
+
+
+### loadSettingsFiles
+
+Load the setting file config defined in `kcl.yaml`
+
+Example
+
+
+The content of `kcl.yaml` is
+
+```yaml
+kcl_cli_configs:
+ strict_range_check: true
+kcl_options:
+ - key: key
+ value: value
+```
+
+Java Code
+
+```java
+import com.kcl.api.*;
+
+API api = new API();
+LoadSettingsFilesArgs args = LoadSettingsFilesArgs.newBuilder().addFiles("kcl.yaml")
+ .build();
+LoadSettingsFilesResult result = api.loadSettingsFiles(args);
+```
+
+
+
+
+### updateDependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
+
+### loadPackage
+
+loadPackage provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+
+### getSchemaTypeMapping
+
+Get schema type mapping defined in the program.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Kotlin Code
+
+```kotlin
+import com.kcl.api.API
+import com.kcl.api.execProgramArgs
+import com.kcl.api.getSchemaTypeMappingArgs
+
+val args = getSchemaTypeMappingArgs { execArgs = execProgramArgs { kFilenameList += "schema.k" } }
+val api = API()
+val result = api.getSchemaTypeMapping(args)
+val appSchemaType = result.schemaTypeMappingMap["app"] ?: throw AssertionError("App schema type not found")
+val replicasAttr = appSchemaType.properties["replicas"] ?: throw AssertionError("App schema type of `replicas` not found")
+```
+
+
+
+
+### overrideFile
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+
+### rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+b = a
+```
+
+Kotlin Code
+
+```kotlin
+import com.kcl.api.API
+import com.kcl.api.renameArgs
+
+val args = renameArgs {
+ packageRoot = "."
+ filePaths += "./main.k"
+ symbolPath = "a"
+ newName = "a2"
+}
+val api = API()
+val result = api.rename(args)
+```
+
+
+
+
+### renameCode
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+
+### updateDependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
+
+### parseFile
+
+Parse KCL single file to Module AST JSON string with import dependencies and parse errors.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Node.js Code
+
+```ts
+import { parseFile, ParseFileArgs } from "kcl-lib";
+
+const result = parseFile(new ParseFileArgs("schema.k"));
+```
+
+
+
+
+### parseProgram
+
+Parse KCL program with entry files and return the AST JSON string.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Node.js Code
+
+```ts
+import { parseProgram, ParseProgramArgs } from "kcl-lib";
+
+const result = parseProgram(new ParseProgramArgs(["schema.k"]));
+```
+
+
+
+
+### loadPackage
+
+loadPackage provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Node.js Code
+
+```ts
+import { loadPackage, LoadPackageArgs } from "kcl-lib";
+
+const result = loadPackage(new LoadPackageArgs(["schema.k"], [], true));
+```
+
+
+
+
+### listVariable
+
+listVariables provides users with the ability to parse KCL program and get all variables by specs.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Node.js Code
+
+```ts
+import { listVariables, ListVariablesArgs } from "kcl-lib";
+
+const result = listVariables(new ListVariablesArgs(["schema.k"], []));
+```
+
+
+
+
+### listOptions
+
+listOptions provides users with the ability to parse KCL program and get all option information.
+
+Example
+
+
+
+### getSchemaTypeMapping
+
+Get schema type mapping defined in the program.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Node.js Code
+
+```ts
+import { getSchemaTypeMapping, GetSchemaTypeMappingArgs } from "kcl-lib";
+
+const result = getSchemaTypeMapping(new GetSchemaTypeMappingArgs(["schema.k"]));
+```
+
+
+
+
+### overrideFile
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {replicas: 4}
+```
+
+Node.js Code
+
+```ts
+import { overrideFile, OverrideFileArgs } from "kcl-lib";
+
+const result = overrideFile(
+ new OverrideFileArgs("main.k", ["app.replicas=4"], []),
+);
+```
+
+
+
+
+### formatPath
+
+Format KCL file or directory path contains KCL files and returns the changed file paths.
+
+Example
+
+
+The content of `format_path.k` is
+
+```python
+schema Person:
+ name: str
+ age: int
+
+ check:
+ 0 < age < 120
+```
+
+Node.js Code
+
+```ts
+import { formatPath, FormatPathArgs } from "kcl-lib";
+
+const result = formatPath(new FormatPathArgs("format_path.k"));
+```
+
+
+
+
+### lintPath
+
+Lint files and return error messages including errors and warnings.
+
+Example
+
+
+The content of `lint_path.k` is
+
+```python
+import math
+
+a = 1
+```
+
+Node.js Code
+
+```ts
+import { lintPath, LintPathArgs } from "kcl-lib";
+
+const result = lintPath(new LintPathArgs(["lint_path.k"]));
+```
+
+
+
+
+### validateCode
+
+Validate code using schema and JSON/YAML data strings.
+
+Example
+
+
+Node.js Code
+
+```ts
+import { validateCode, ValidateCodeArgs } from "kcl-lib";
+
+const code = `
+schema Person:
+ name: str
+ age: int
+
+ check:
+ 0 < age < 120
+`;
+const data = '{"name": "Alice", "age": 10}';
+const result = validateCode(
+ new ValidateCodeArgs(undefined, data, undefined, code),
+);
+```
+
+
+
+
+### rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+b = a
+```
+
+Node.js Code
+
+```ts
+import { rename, RenameArgs } from "kcl-lib";
+
+const args = new RenameArgs(".", "a", ["main.k"], "a2");
+const result = rename(args);
+```
+
+
+
+
+### renameCode
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+
+### test
+
+Test KCL packages with test arguments.
+
+Example
+
+
+Node.js Code
+
+```ts
+import { test as kclTest, TestArgs } from "kcl-lib";
+
+const result = kclTest(new TestArgs(["/path/to/test/module/..."]));
+```
+
+
+
+
+### loadSettingsFiles
+
+Load the setting file config defined in `kcl.yaml`
+
+Example
+
+
+The content of `kcl.yaml` is
+
+```yaml
+kcl_cli_configs:
+ strict_range_check: true
+kcl_options:
+ - key: key
+ value: value
+```
+
+Node.js Code
+
+```ts
+import { loadSettingsFiles, LoadSettingsFilesArgs } from "kcl-lib";
+
+const result = loadSettingsFiles(new LoadSettingsFilesArgs(".", ["kcl.yaml"]));
+```
+
+
+
+
+### updateDependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
+
+### getVersion
+
+Return the KCL service version information.
+
+Example
+
+
+Node.js Code
+
+```ts
+import { getVersion } from "../index.js";
+
+const result = getVersion();
+console.log(result.versionInfo);
+```
+
+
+
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/overview.md
new file mode 100644
index 000000000..8ce491ae2
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/overview.md
@@ -0,0 +1,125 @@
+---
+sidebar_position: 1
+---
+
+# Introduction
+
+The KCL language provides multiple general-purpose programming language interfaces, with identical API forms and features.
+
+## C/Rust APIs
+
+The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in other high-level languages such as Go, Python, etc.
+
+## REST-API
+
+The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf.
+
+### Start REST Service
+
+The RestAPI service can be started in the following way:
+
+```shell
+kcl server
+```
+
+The service can then be requested via the POST protocol:
+
+```shell
+curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}'
+```
+
+The output is
+
+```json
+{
+ "error": "",
+ "result": {}
+}
+```
+
+The POST request and the returned JSON data are consistent with the structure defined by Protobuf.
+
+### `BuiltinService`
+
+Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service.
+
+The complete `BuiltinService` is defined by Protobuf:
+
+```protobuf
+service BuiltinService {
+ rpc Ping(PingArgs) returns(PingResult);
+ rpc ListMethod(ListMethodArgs) returns(ListMethodResult);
+}
+
+message PingArgs {
+ string value = 1;
+}
+message PingResult {
+ string value = 1;
+}
+
+message ListMethodArgs {
+ // empty
+}
+message ListMethodResult {
+ repeated string method_name_list = 1;
+}
+```
+
+The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided.
+
+### `KclService`
+
+The `KclService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service.
+
+For example, there is the following `Person` structure definition:
+
+```python
+schema Person:
+ key: str
+
+ check:
+ "value" in key # 'key' is required and 'key' must contain "value"
+```
+
+Then we want to use `Person` to verify the following JSON data:
+
+```json
+{ "key": "value" }
+```
+
+This can be done through the `ValidateCode` method of the `KclService` service. Refer to the `ValidateCodeArgs` structure of the `ValidateCode` method:
+
+```protobuf
+message ValidateCodeArgs {
+ string data = 1;
+ string code = 2;
+ string schema = 3;
+ string attribute_name = 4;
+ string format = 5;
+}
+```
+
+Construct the JSON data required by the POST request according to the `ValidateCodeArgs` structure, which contains the `Person` definition and the JSON data to be verified:
+
+```json
+{
+ "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n",
+ "data": "{\"key\": \"value\"}"
+}
+```
+
+Save this JSON data to the `vet-hello.json` file and verify it with the following command:
+
+```shell
+$ curl -X POST \
+ http://127.0.0.1:2021/api:protorpc/KclService.ValidateCode \
+ -H "accept: application/json" \
+ --data @./vet-hello.json
+{
+ "error": "",
+ "result": {
+ "success": true
+ }
+}
+```
diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/python-api.md
new file mode 100644
index 000000000..c8d7064ad
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.12/reference/xlang-api/python-api.md
@@ -0,0 +1,673 @@
+---
+sidebar_position: 4
+---
+
+# Python API
+
+## Installation
+
+```shell
+python3 -m pip install kcl-lib
+```
+
+## Quick Start
+
+```typescript
+import kcl_lib.api as api
+
+args = api.ExecProgramArgs(k_filename_list=["path/to/kcl.k"])
+api = api.API()
+result = api.exec_program(args)
+print(result.yaml_result)
+```
+
+## API Reference
+
+### exec_program
+
+Execute KCL file with arguments and return the JSON/YAML result.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Python Code
+
+```python
+import kcl_lib.api as api
+
+args = api.ExecProgramArgs(k_filename_list=["schema.k"])
+api = api.API()
+result = api.exec_program(args)
+assert result.yaml_result == "app:\n replicas: 2"
+```
+
+
+
+
+A case with the file not found error
+
+Example
+
+
+```python
+import kcl_lib.api as api
+
+try:
+ args = api.ExecProgramArgs(k_filename_list=["file_not_found"])
+ api = api.API()
+ result = api.exec_program(args)
+ assert False
+except Exception as err:
+ assert "Cannot find the kcl file" in str(err)
+```
+
+
+
+
+### parse_file
+
+Parse KCL single file to Module AST JSON string with import dependencies and parse errors.
+
+Example
+
+
+The content of `schema.k` is
+
+```python
+schema AppConfig:
+ replicas: int
+
+app: AppConfig {
+ replicas: 2
+}
+```
+
+Python Code
+
+```python
+import kcl_lib.api as api
+
+args = api.ParseFileArgs(path=TEST_FILE)
+api = api.API()
+result = api.parse_file(args)
+assert len(result.errors) == 0
+```
+
+
+
+
+### parse_program
+
+Parse KCL program with entry files and return the AST JSON string.
+
+Example
+
+
+
+### load_package
+
+load_package provides users with the ability to parse KCL program and semantic model information including symbols, types, definitions, etc.
+
+Example
+
+
+
+### override_file
+
+Override KCL file with arguments. See [https://www.kcl-lang.io/docs/user_docs/guides/automation](https://www.kcl-lang.io/docs/user_docs/guides/automation) for more override spec guide.
+
+Example
+
+
+
+### rename
+
+Rename all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. Return the file paths that got changed.
+
+Example
+
+
+The content of `main.k` is
+
+```python
+a = 1
+b = a
+```
+
+Python Code
+
+```python
+import kcl_lib.api as api
+
+args = api.RenameArgs(
+ package_root=".",
+ symbol_path="a",
+ file_paths=["main.k"],
+ new_name="a2",
+)
+api_instance = api.API()
+result = api_instance.rename(args)
+```
+
+
+
+
+### rename_code
+
+Rename all the occurrences of the target symbol and return the modified code if any code has been changed. This API won't rewrite files but return the changed code.
+
+Example
+
+
+
+### update_dependencies
+
+Download and update dependencies defined in the `kcl.mod` file and return the external package name and location list.
+
+Example
+
+
+The content of `module/kcl.mod` is
+
+```yaml
+[package]
+name = "mod_update"
+edition = "0.0.1"
+version = "0.0.1"
+
+[dependencies]
+helloworld = { oci = "oci://ghcr.io/kcl-lang/helloworld", tag = "0.1.0" }
+flask = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests", commit = "ade147b" }
+```
+
+Python Code
+
+```python
+import kcl_lib.api as api
+
+args = api.UpdateDependenciesArgs(
+ manifest_path="module"
+)
+api_instance = api.API()
+result = api_instance.update_dependencies(args)
+pkg_names = [pkg.pkg_name for pkg in result.external_pkgs]
+assert len(pkg_names) == 2
+assert "helloworld" in pkg_names
+assert "flask" in pkg_names
+```
+
+
+
+
+Call `exec_program` with external dependencies
+
+Example
+
+
+
+### validate_code
+
+Service for validating the data string using the schema code string, when the parameter schema is omitted, use the first schema appeared in the kcl code.
+
+Example
+
+
+
+### rename
+
+Service for renaming all the occurrences of the target symbol in the files. This API will rewrite files if they contain symbols to be renamed. return the file paths got changed.
+
+Example
+
+
+
+### rename_code
+
+Service for renaming all the occurrences of the target symbol and rename them. This API won’t rewrite files but return the modified code if any code has been changed. return the changed code.
+
+Example
+