// Copyright 2020 CUE Authors // // 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. package build // This file describes how various cross-cutting modes influence default // settings. // // It is used by types.go to compile a cue.Value, which is then // used by the rest of the package to determine settings. // A File corresponds to a Go build.File. #File: { filename?: string // only filled in FromFile, but not in ParseFile encoding!: #Encoding interpretation?: #Interpretation form?: #Form // Note: tags includes values for non-boolean tags only. tags?: [string]: string boolTags?: [string]: bool } // A FileInfo defines how a file is encoded and interpreted. #FileInfo: { #File // For each of these fields it is explained what a true value means // for encoding/decoding. data: *true | false // include/allow regular fields references: *true | false // don't resolve/allow references cycles: *true | false // cycles are permitted definitions?: bool // include/allow definition fields optional?: bool // include/allow definition fields constraints?: bool // include/allow constraints keepDefaults?: bool // select/allow default values incomplete?: bool // permit incomplete values imports?: bool // don't expand/allow imports stream?: bool // permit streaming docs?: bool // show/allow docs attributes?: bool // include/allow attributes } // fileForExtVanilla holds the extensions supported in // input mode with scope="" - the most common form // of file type to evaluate. // // It's also used as a source of truth for all known file // extensions as all modes define attributes for // all file extensions. If that ever changed, we'd need // to change this. fileForExtVanilla: modes.input.extensions // #Mode represents an overall mode that CUE is being run in // (e.g. eval, export). #Mode: { // FileInfo holds the base file information for this mode. // This will be unified with information derived from the // file extension and any filetype tags explicitly provided. FileInfo!: #FileInfo // extensions holds the set of file extensions that are defined // for this mode. extensions!: [_]: #FileInfo // encodings holds the set of encodings defined for this mode. encodings!: [_]: #FileInfo } // modes sets defaults for different operational modes. // The key corresponds to the Go internal/filetypes.Mode type. modes: [string]: #Mode // input defines modes for input, such as import, eval, vet or def. // In input mode, settings flags are interpreted as what is allowed to occur // in the input. The default settings, therefore, tend to be permissive. modes: input: { // FileInfo holds a value that's unified with the file value. FileInfo: { docs: *true | false attributes: *true | false } // encodings is unified to the file value when interpretation is empty. encodings: cue: { *forms.schema | _ } extensions: "-": encoding: *"cue" | _ extensions: ".json": interpretation: *"auto" | _ extensions: ".yaml": interpretation: *"auto" | _ extensions: ".yml": interpretation: *"auto" | _ extensions: ".toml": interpretation: *"auto" | _ extensions: ".ini": interpretation: *"auto" | _ extensions: ".xml": interpretation: *"auto" | _ } modes: export: { FileInfo: { docs: true | *false attributes: true | *false } encodings: cue: forms.data extensions: "-": encoding: *"json" | _ } // eval is a legacy mode modes: eval: { FileInfo: { docs: true | *false attributes: true | *false } encodings: cue: forms.final extensions: "-": encoding: *"cue" | _ } modes: def: { FileInfo: { docs: *true | false attributes: *true | false } encodings: cue: forms.schema extensions: "-": encoding: *"cue" | _ } // A Encoding indicates a file format for representing a program. #Encoding: !="" // | error("no encoding specified") // An Interpretation determines how a certain program should be interpreted. // For instance, data may be interpreted as describing a schema, which itself // can be converted to a CUE schema. // This corresponds to the Go cue/build.Interpretation type. #Interpretation: string // A Form specifies the form in which a program should be represented. // It corresponds to the Go cue/build.Form type. #Form: string all: { for m in modes { for name, _ in m.encodings { encodings: (name): true } for name, _ in m.extensions { extensions: (name): true } } for name, _ in interpretations { interpretations: (name): true } for name, _ in forms { forms: (name): true } } modes: [string]: { // extensions maps a file extension to its associated default file properties. extensions: { ".cue": tagInfo.cue ".json": tagInfo.json ".jsonl": tagInfo.jsonl ".ldjson": tagInfo.jsonl ".ndjson": tagInfo.jsonl ".yaml": tagInfo.yaml ".yml": tagInfo.yaml ".toml": tagInfo.toml ".ini": tagInfo.ini ".xml": tagInfo.xml ".txt": tagInfo.text ".go": tagInfo.go ".wasm": tagInfo.binary ".proto": tagInfo.proto ".textproto": tagInfo.textproto ".textpb": tagInfo.textproto // perhaps also pbtxt // TODO: jsonseq, // ".pb": tagInfo.binpb // binarypb } // encodings: "": error("no encoding specified") encodings: cue: { stream: false } encodings: json: { forms.data stream: *false | true docs: false attributes: false } encodings: yaml: { forms.graph stream: false | *true } encodings: jsonl: { forms.data stream: true } encodings: text: { forms.data stream: false } encodings: binary: { forms.data stream: false } encodings: toml: { forms.data stream: false } encodings: ini: { forms.data stream: false } encodings: xml: { forms.data stream: false } encodings: proto: { forms.schema encoding: "proto" } encodings: textproto: { forms.data encoding: "textproto" stream: false } encodings: binarypb: { forms.data encoding: "binarypb" stream: false } encodings: code: { forms.schema stream: false } } // forms defines schema for all forms. It does not include the form ID. forms: [Name=string]: #FileInfo forms: schema: { form: *"schema" | "final" | "graph" stream: true | *false incomplete: *true | false definitions: *true | false optional: *true | false constraints: *true | false keepDefaults: *true | false imports: *true | false } forms: final: { form: "final" forms.schema keepDefaults: false optional: false } forms: graph: { form: *"graph" | "dag" | "data" data: true incomplete: false definitions: false optional: false constraints: false keepDefaults: false imports: false } forms: dag: { form: !="graph" forms.graph cycles: false } forms: data: { form: !="dag" forms.dag constraints: false references: false cycles: false imports: false optional: false } interpretations: [Name=string]: #FileInfo & { interpretation: Name } interpretations: auto: forms.schema interpretations: jsonschema: { forms.schema encoding: *"json" | _ boolTags: { strict: *false | bool strictKeywords: *strict | bool // TODO: enable strictFeatures by default? (see https://cuelang.org/issue/3923). strictFeatures: *strict | bool openOnlyWhenExplicit: *false | bool } } interpretations: openapi: { forms.schema encoding: *"json" | _ boolTags: { strict: *false | bool strictKeywords: *strict | bool strictFeatures: *strict | bool } } interpretations: pb: { forms.data stream: true } tagInfo: [_]: #FileInfo // tagInfo maps command line tags to file properties. tagInfo: { schema: form: "schema" graph: form: "graph" dag: form: "dag" data: form: "data" cue: encoding: "cue" json: encoding: "json" jsonl: encoding: "jsonl" yaml: encoding: "yaml" toml: encoding: "toml" ini: encoding: "ini" xml: { encoding: "xml" boolTags: { // We implement XML variants as boolean tags, such that "koala" is not accessible // as a top-level filetype, and can only be used via "xml+koala". // These effectively behave like a "one of", but we enforce this via the Go code // so that we can provide the users with good error messages. koala: *false | bool } } proto: encoding: "proto" textproto: encoding: "textproto" // "binpb": encodings.binproto // pb is used either to indicate binary encoding, or to indicate pb: *{ encoding: "binarypb" interpretation: "" } | { encoding: !="binarypb" interpretation: "pb" } text: { encoding: "text" form: "data" } binary: { encoding: "binary" form: "data" } go: { encoding: "code" interpretation: "" tags: lang: "go" } code: { encoding: "code" interpretation: "" tags: lang: *"" | string } auto: interpretations.auto & { encoding: *"json" | string } jsonschema: interpretations.jsonschema openapi: interpretations.openapi }