diff --git a/syntaxes/proto.tmLanguage.json b/syntaxes/proto.tmLanguage.json index 5c581a7..0f912cf 100644 --- a/syntaxes/proto.tmLanguage.json +++ b/syntaxes/proto.tmLanguage.json @@ -1,679 +1,507 @@ { - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "Protocol Buffers", + "$schema": "https://json.schemastore.org/tmLanguage.json", + "name": "Protocol Buffer 3", + "scopeName": "source.proto", + "fileTypes": [ + "proto" + ], "patterns": [ { - "include": "#syntax" + "include": "#comments" }, { - "include": "#edition" - }, - { - "include": "#import" + "include": "#syntax" }, { "include": "#package" - }, - { - "include": "#message" }, { - "include": "#field-extends" + "include": "#import" }, { - "include": "#option" + "include": "#optionStmt" }, { - "include": "#service" + "include": "#message" }, { "include": "#enum" }, { - "include": "#comment" + "include": "#service" } ], "repository": { - "syntax": { - "name": "meta.syntax.proto", - "begin": "\\b(syntax)\\s*(=)\\s*", - "beginCaptures": { - "1": { - "name": "keyword.syntax.proto" - }, - "2": { - "name": "punctuation.separator.key-value.proto" - } - }, - "end": "\\;", - "endCaptures": { - "0": { - "name": "punctuation.terminator.proto" - } - }, - "contentName": "meta.syntax.value.proto", + "comments": { "patterns": [ { - "include": "#qstring-single" + "name": "comment.block.proto", + "begin": "/\\*", + "end": "\\*/" }, { - "include": "#qstring-double" + "name": "comment.line.double-slash.proto", + "begin": "//", + "end": "$\\n?" } ] }, - "edition": { - "name": "meta.edition.proto", - "begin": "\\b(edition)\\s*(=)\\s*", - "beginCaptures": { + "syntax": { + "match": "\\s*(syntax)\\s*(=)\\s*(\"proto[23]\")\\s*(;)", + "captures": { "1": { - "name": "keyword.edition.proto" + "name": "keyword.other.proto" }, "2": { - "name": "punctuation.separator.key-value.proto" - } - }, - "end": "\\;", - "endCaptures": { - "0": { - "name": "punctuation.terminator.proto" - } - }, - "contentName": "meta.edition.value.proto", - "patterns": [ - { - "include": "#qstring-single" + "name": "keyword.operator.assignment.proto" }, - { - "include": "#qstring-double" + "3": { + "name": "string.quoted.double.proto.syntax" + }, + "4": { + "name": "punctuation.terminator.proto" } - ] + } }, - "import": { - "name": "meta.import.proto", - "begin": "\\b(import)\\s*", - "beginCaptures": { + "package": { + "match": "\\s*(package)\\s+([\\w.]+)\\s*(;)", + "captures": { "1": { - "name": "keyword.import.proto" - } - }, - "end": "\\;", - "endCaptures": { - "0": { - "name": "punctuation.terminator.proto" - } - }, - "contentName": "meta.import.value.proto", - "patterns": [ - { - "include": "#qstring-single" + "name": "keyword.other.proto" }, - { - "include": "#qstring-double" + "2": { + "name": "string.unquoted.proto.package" + }, + "3": { + "name": "punctuation.terminator.proto" } - ] + } }, - "package": { - "name": "meta.package.proto", - "begin": "\\b(package)\\b([^\\;]*)", - "beginCaptures": { + "import": { + "match": "\\s*(import)\\s+(weak|public)?\\s*(\"[^\"]+\")\\s*(;)", + "captures": { "1": { - "name": "keyword.package.proto" + "name": "keyword.other.proto" }, "2": { - "name": "entity.name.section.package.proto" - } - }, - "end": "\\;", - "endCaptures": { - "0": { + "name": "keyword.other.proto" + }, + "3": { + "name": "string.quoted.double.proto.import" + }, + "4": { "name": "punctuation.terminator.proto" } } }, - "option": { - "name": "meta.option.proto", - "begin": "\\b(option)\\b\\s*([a-zA-Z0-9\\-\\_]+)\\s*(=)\\s*", + "optionStmt": { + "begin": "(option)\\s+(\\w+|\\(\\w+(\\.\\w+)*\\))(\\.\\w+)*\\s*(=)", "beginCaptures": { "1": { - "name": "keyword.option.proto" + "name": "keyword.other.proto" }, "2": { - "name": "variable.name.option.proto" + "name": "support.other.proto" }, "3": { - "name": "punctuation.separator.key-value.proto" + "name": "support.other.proto" + }, + "4": { + "name": "support.other.proto" + }, + "5": { + "name": "keyword.operator.assignment.proto" } }, - "end": "\\;", + "end": "(;)", "endCaptures": { - "0": { + "1": { "name": "punctuation.terminator.proto" } }, "patterns": [ { - "include": "#qstring-single" + "include": "#constants" }, { - "include": "#qstring-double" + "include": "#number" }, { - "include": "#boolean" + "include": "#string" }, { - "name": "entity.name.type.option.value.proto", - "match": "[^\\;]*" + "include": "#subMsgOption" } ] }, - "message": { - "name": "statement.message.proto", - "begin": "\\b(message)\\b\\s*([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", + "subMsgOption": { + "begin": "\\{", + "end": "\\}", + "patterns": [ + { + "include": "#kv" + }, + { + "include": "#comments" + } + ] + }, + "kv": { + "begin": "(\\w+)\\s*(:)", "beginCaptures": { "1": { - "name": "keyword.message.proto" + "name": "keyword.other.proto" }, "2": { - "name": "entity.name.type.message.proto" - }, - "3": { - "name": "punctuation.definition.message.begin.proto" + "name": "punctuation.separator.key-value.proto" } }, - "end": "\\}", + "end": "(;)|,|(?=[}/_a-zA-Z])", "endCaptures": { - "0": { - "name": "punctuation.definition.message.end.proto" + "1": { + "name": "punctuation.terminator.proto" } }, "patterns": [ { - "include": "#comment" - }, - { - "include": "#option" - }, - { - "include": "#field-group" + "include": "#constants" }, { - "include": "#field-statement" + "include": "#number" }, { - "include": "#field-extends" + "include": "#string" }, { - "include": "#field-oneof" - }, + "include": "#subMsgOption" + } + ] + }, + "fieldOptions": { + "begin": "\\[", + "end": "\\]", + "patterns": [ { - "include": "#message" + "include": "#constants" }, { - "include": "#enum" + "include": "#number" }, { - "include": "#reserved-field" + "include": "#string" }, { - "include": "#field-extensions" + "include": "#subMsgOption" }, { - "include": "#extend" + "include": "#optionName" } ] }, - "enum": { - "name": "statement.enum.proto", - "begin": "\\b(enum)\\b\\s*([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", - "beginCaptures": { + "optionName": { + "match": "(\\w+|\\(\\w+(\\.\\w+)*\\))(\\.\\w+)*", + "captures": { "1": { - "name": "keyword.enum.proto" + "name": "support.other.proto" }, "2": { - "name": "entity.name.type.enum.proto" + "name": "support.other.proto" }, "3": { - "name": "punctuation.definition.enum.begin.proto" - } - }, - "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.enum.end.proto" + "name": "support.other.proto" } - }, - "patterns": [ - { - "include": "#comment" - }, - { - "include": "#enum-value" - } - ] + } }, - "extend": { - "name": "statement.extend.proto", - "begin": "\\b(extend)\\b\\s*([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", + "message": { + "begin": "(message|extend)(\\s+)([A-Za-z_][A-Za-z0-9_.]*)(\\s*)(\\{)?", "beginCaptures": { "1": { - "name": "keyword.extend.proto" - }, - "2": { - "name": "entity.name.type.extend.proto" + "name": "keyword.other.proto" }, "3": { - "name": "punctuation.definition.extend.begin.proto" + "name": "entity.name.class.message.proto" } }, "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.extend.end.proto" - } - }, "patterns": [ { - "include": "#comment" + "include": "#reserved" }, { - "include": "#field-statement" - } - ] - }, - "service": { - "name": "statement.service.proto", - "begin": "\\b(service)\\b\\s*([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", - "beginCaptures": { - "1": { - "name": "keyword.service.proto" + "include": "$self" }, - "2": { - "name": "entity.name.type.service.proto" + { + "include": "#enum" }, - "3": { - "name": "punctuation.definition.service.begin.proto" - } - }, - "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.service.end.proto" - } - }, - "patterns": [ { - "include": "#comment" + "include": "#optionStmt" }, { - "include": "#captured-options" + "include": "#comments" }, { - "include": "#rpc-method" + "include": "#oneof" + }, + { + "include": "#field" + }, + { + "include": "#mapfield" } ] }, - "empty": { - - }, - "comment": { + "reserved": { + "begin": "(reserved)\\s+", + "beginCaptures": { + "1": { + "name": "keyword.other.proto" + } + }, + "end": "(;)", + "endCaptures": { + "1": { + "name": "punctuation.terminator.proto" + } + }, "patterns": [ { - "name": "comment.block.documentation.proto", - "begin": "/\\*\\*(?!/)", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.proto" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.proto" + "match": "(\\d+)(\\s+(to)\\s+(\\d+))?", + "captures": { + "1": { + "name": "constant.numeric.proto" + }, + "3": { + "name": "keyword.other.proto" + }, + "4": { + "name": "constant.numeric.proto" } } }, { - "name": "comment.block.proto", - "begin": "/\\*", - "end": "\\*/" - }, - { - "name": "comment.line.double-slash.proto", - "begin": "//", - "end": "(?:\\n|$)" + "include": "#string" } ] }, - "qstring-single": { - "name": "string.quoted.single.proto", - "match": "'(?:\\\\x[0-9a-f]{2}|\\\\[0-7]{3}|\\\\[0-7]|\\\\[abfnrtv\\\\\\?'\"]|[^'\\0\\n\\\\])*'" - }, - "qstring-double": { - "name": "string.quoted.double.proto", - "match": "\"(?:\\\\x[0-9a-f]{2}|\\\\[0-7]{3}|\\\\[0-7]|\\\\[abfnrtv\\\\\\?'\"]|[^\"\\0\\n\\\\])*\"" - }, - "boolean": { - "name": "constant.language.boolean.proto", - "match": "(true)|(false)" - }, - "identifier": { - "name": "variable.name.proto", - "match": "\\b[a-z_][a-z0-9_]\\b" - }, - "enum-value": { - "name": "statement.enum-value.proto", - "begin": "\\b([a-zA-Z0-9\\-\\_]+)\\s*(=)\\s*", + "field": { + "begin": "\\s*(optional|repeated|required)?\\s*\\b([\\w.]+)\\s+(\\w+)\\s*(=)\\s*(0[xX][0-9a-fA-F]+|[0-9]+)", "beginCaptures": { "1": { - "name": "entity.name.type.enum-value.proto" + "name": "storage.modifier.proto" }, "2": { - "name": "punctuation.separator.key-value.proto" + "name": "storage.type.proto" + }, + "3": { + "name": "variable.other.proto" + }, + "4": { + "name": "keyword.operator.assignment.proto" + }, + "5": { + "name": "constant.numeric.proto" } }, - "end": "\\;", + "end": "(;)", "endCaptures": { - "0": { + "1": { "name": "punctuation.terminator.proto" } }, - "contentName": "statement.enum.fieldnumber.proto", "patterns": [ { - "name": "constant.numeric.proto", - "match": "[0-9]+" + "include": "#fieldOptions" } ] }, - "field-statement": { - "name": "statement.field.proto", - "begin": "\\b(required|optional|repeated)?\\s*(?:(double|string|(?:(?:(?:(?:u|s)?int)|s?fixed)(?:32|64))|bool|bytes)|([a-zA-Z0-9\\-\\_\\.]+)|(?:(map)\\s*(<)\\s*(?:(double|string|(?:(?:(?:(?:u|s)?int)|s?fixed)(?:32|64))|bool|bytes)|([a-zA-Z0-9\\-\\_\\.]+))\\s*(,)\\s*(?:(double|string|(?:(?:(?:(?:u|s)?int)|s?fixed)(?:32|64))|bool|bytes)|([a-zA-Z0-9\\-\\_\\.]+))\\s*(>)))\\s+([a-zA-Z0-9\\-\\_]+)\\s*(=)\\s*([0-9]+)\\s*", + "mapfield": { + "begin": "\\s*(map)\\s*(<)\\s*([\\w.]+)\\s*,\\s*([\\w.]+)\\s*(>)\\s+(\\w+)\\s*(=)\\s*(\\d+)", "beginCaptures": { "1": { - "name": "keyword.field.type.proto" + "name": "storage.type.proto" }, "2": { - "name": "support.type.field.proto" + "name": "punctuation.definition.typeparameters.begin.proto" }, "3": { - "name": "entity.name.type.field.proto" + "name": "storage.type.proto" }, "4": { - "name": "keyword.map.proto" + "name": "storage.type.proto" }, "5": { - "name": "punctuation.start.map.proto" + "name": "punctuation.definition.typeparameters.end.proto" }, "6": { - "name": "support.type.field.proto" + "name": "variable.other.proto" }, "7": { - "name": "entity.name.type.field.proto" + "name": "keyword.operator.assignment.proto" }, "8": { - "name": "punctuation.separator.map.proto" - }, - "9": { - "name": "support.type.field.proto" - }, - "10": { - "name": "entity.name.type.field.proto" - }, - "11": { - "name": "punctuation.end.map.proto" - }, - "12": { - "name": "variable.name.field.proto" - }, - "13": { - "name": "punctuation.separator.key-value.proto" - }, - "14": { "name": "constant.numeric.proto" } }, - "end": "\\;", + "end": "(;)", "endCaptures": { - "0": { + "1": { "name": "punctuation.terminator.proto" } }, - "contentName": "statement.field.option.proto", "patterns": [ { - "include": "#field-option" + "include": "#fieldOptions" } ] }, - "reserved-field": { - "name": "statement.reserved-field.proto", - "begin": "\\b(reserved)\\b", + "oneof": { + "begin": "(oneof)\\s+([A-Za-z][A-Za-z0-9_]*)\\s*\\{?", "beginCaptures": { "1": { - "name": "keyword.reserved.proto" - } - }, - "end": "\\;", - "endCaptures": { - "0": { - "name": "punctuation.terminator.proto" + "name": "keyword.other.proto" + }, + "2": { + "name": "variable.other.proto" } }, + "end": "\\}", "patterns": [ { - "name": "constant.numeric.proto", - "match": "[0-9]+" + "include": "#optionStmt" }, { - "name": "keyword.operator.range.proto", - "match": "to" + "include": "#comments" }, { - "include": "#qstring-single" - }, - { - "include": "#qstring-double" + "include": "#field" } ] }, - "field-option": { - "name": "statement.field-option.proto", - "begin": "(\\[)([a-zA-Z0-9\\-\\_]+)\\s*(=)\\s*", + "enum": { + "begin": "(enum)(\\s+)([A-Za-z][A-Za-z0-9_]*)(\\s*)(\\{)?", "beginCaptures": { "1": { - "name": "punctuation.definition.field-option.proto" - }, - "2": { - "name": "support.constant.field-option.proto" + "name": "keyword.other.proto" }, "3": { - "name": "punctuation.separator.key-value.proto" - } - }, - "end": "\\]", - "endCaptures": { - "0": { - "name": "punctuation.definition.field-option.proto" + "name": "entity.name.class.proto" } }, + "end": "\\}", "patterns": [ { - "include": "#boolean" + "include": "#reserved" }, { - "name": "entity.name.type.option.value.proto", - "match": "\\b[a-zA-Z0-9\\-\\_]+\\b" - } - ] - }, - "field-oneof": { - "name": "statement.field-oneof.proto", - "begin": "\\b(oneof)\\s+([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", - "beginCaptures": { - "1": { - "name": "keyword.oneof.proto" - }, - "2": { - "name": "entity.name.type.oneof.proto" + "include": "#optionStmt" }, - "3": { - "name": "punctuation.definition.extend.begin.proto" - } - }, - "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.extend.end.proto" - } - }, - "patterns": [ { - "include": "#field-statement" + "include": "#comments" }, { - "include": "#comment" + "begin": "([A-Za-z][A-Za-z0-9_]*)\\s*(=)\\s*(0[xX][0-9a-fA-F]+|[0-9]+)", + "beginCaptures": { + "1": { + "name": "variable.other.proto" + }, + "2": { + "name": "keyword.operator.assignment.proto" + }, + "3": { + "name": "constant.numeric.proto" + } + }, + "end": "(;)", + "endCaptures": { + "1": { + "name": "punctuation.terminator.proto" + } + }, + "patterns": [ + { + "include": "#fieldOptions" + } + ] } ] }, - "field-group": { - "name": "statement.field-group.proto", - "begin": "\\b(required|optional|repeated)?\\s*(group)\\s+([a-zA-Z0-9\\-\\_]+)\\s*(=)\\s*(\\d+)\\s*(\\{)", + "service": { + "begin": "(service)\\s+([A-Za-z][A-Za-z0-9_.]*)\\s*\\{?", "beginCaptures": { "1": { - "name": "keyword.group.type.proto" + "name": "keyword.other.proto" }, "2": { - "name": "keyword.group.proto" - }, - "3": { - "name": "entity.name.type.group.proto" - }, - "4": { - "name": "punctuation.separator.key-value.proto" - }, - "5": { - "name": "constant.numeric.proto" - }, - "6": { - "name": "punctuation.definition.extend.begin.proto" + "name": "entity.name.class.message.proto" } }, "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.extend.end.proto" - } - }, "patterns": [ { - "include": "#field-statement" - } - ] - }, - "field-extends": { - "name": "statement.field-extends.proto", - "begin": "\\b(extend)\\s+([a-zA-Z0-9\\-\\_]+)\\s*(\\{)", - "beginCaptures": { - "1": { - "name": "keyword.extend.proto" + "include": "#comments" }, - "2": { - "name": "entity.name.type.extend.proto" + { + "include": "#optionStmt" }, - "3": { - "name": "punctuation.definition.extend.begin.proto" - } - }, - "end": "\\}", - "endCaptures": { - "0": { - "name": "punctuation.definition.extend.end.proto" - } - }, - "patterns": [ { - "include": "#field-statement" + "include": "#method" } ] }, - "field-extensions": { - "name": "statement.field-extensions.proto", - "begin": "\\b(extensions)\\b", + "method": { + "begin": "(rpc)\\s+([A-Za-z][A-Za-z0-9_]*)", "beginCaptures": { "1": { - "name": "keyword.extensions.proto" + "name": "keyword.other.proto" + }, + "2": { + "name": "entity.name.function" } }, - "end": "\\;", + "end": "\\}|(;)", "endCaptures": { - "0": { + "1": { "name": "punctuation.terminator.proto" } }, "patterns": [ { - "name": "constant.numeric.proto", - "match": "[0-9]+" + "include": "#comments" }, { - "name": "keyword.operator.range.proto", - "match": "to" + "include": "#optionStmt" }, { - "name": "constant.language.max.proto", - "match": "max" - } - ] - }, - "rpc-method": { - "name": "statement.rpc-method.proto", - "match": "\\b(rpc)\\s+([0-9a-zA-Z\\-\\_]+)\\s*(\\()\\s*((stream\\s*)?[a-zA-Z0-9\\-\\_\\.]+)\\s*(\\))\\s*(returns)\\s*(\\()\\s*((stream\\s*)?[a-zA-Z0-9\\-\\_\\.]+)\\s*(\\))\\s*(\\;)?", - "captures": { - "1": { - "name": "keyword.rpc.proto" - }, - "2": { - "name": "entity.name.function.rpc.proto" - }, - "3": { - "name": "punctuation.definition.parameters.begin.proto" - }, - "4": { - "name": "entity.name.type.request.proto" - }, - "5": { - "name": "keyword.rpc.type.proto" + "include": "#rpcKeywords" }, - "6": { - "name": "punctuation.definition.parameters.end.proto" - }, - "7": { - "name": "keyword.returns.proto" - }, - "8": { - "name": "punctuation.definition.parameters.begin.proto" - }, - "9": { - "name": "entity.name.type.response.proto" - }, - "10": { - "name": "keyword.rpc.type.proto" - }, - "11": { - "name": "punctuation.definition.parameters.end.proto" - } - } - }, - "captured-options": { - "name": "statement.captured-options.proto", - "begin": "{", - "end": "}", - "patterns": [ { - "include": "#option" + "include": "#ident" } ] + }, + "rpcKeywords": { + "match": "\\b(stream|returns)\\b", + "name": "keyword.other.proto" + }, + "ident": { + "match": "[A-Za-z][A-Za-z0-9_]*", + "name": "entity.name.class.proto" + }, + "constants": { + "match": "\\b(true|false|max|[A-Z_]+)\\b", + "name": "constant.language.proto" + }, + "storagetypes": { + "match": "\\b(double|float|int32|int64|uint32|uint64|sint32|sint64|fixed32|fixed64|sfixed32|sfixed64|bool|string|bytes)\\b", + "name": "storage.type.proto" + }, + "string": { + "match": "('([^']|\\')*')|(\"([^\"]|\\\")*\")", + "name": "string.quoted.double.proto" + }, + "number": { + "name": "constant.numeric.proto", + "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b" } - }, - "scopeName": "source.proto" -} + } +} \ No newline at end of file diff --git a/syntaxes/prototext.tmLanguage.json b/syntaxes/prototext.tmLanguage.json index b25b32a..1247b3b 100644 --- a/syntaxes/prototext.tmLanguage.json +++ b/syntaxes/prototext.tmLanguage.json @@ -1,121 +1,306 @@ { - "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "Protocol Buffers Text Format", + "$schema": "https://json.schemastore.org/tmLanguage.json", + "name": "Protocol Buffer Text Format", + "scopeName": "source.textproto", + "fileTypes": [ + "pbtxt", + "prototxt", + "textproto" + ], + "foldingStartMarker": "(\\{|\\[)\\s*$", + "foldingStopMarker": "^\\s*(\\}|\\])\\s*$", "patterns": [ { - "include": "#dictionary" + "include": "#comments" + }, + { + "include": "#string-single" + }, + { + "include": "#string-double" }, { - "include": "#kv-pair" + "include": "#key" }, { - "include": "#comment" + "include": "#optional-key" + }, + { + "include": "#field" } ], "repository": { - "dictionary": { - "name": "meta.dictionary.prototext", - "begin": "\\b(?:([a-zA-Z]+[a-zA-Z0-9_]*)|([0-9]+))\\s*({)", + "array": { + "begin": "\\[", "beginCaptures": { - "1": { - "name": "support.type.prototext" + "0": { + "name": "punctuation.definition.array.begin.textproto" + } + }, + "end": "\\]", + "endCaptures": { + "0": { + "name": "punctuation.definition.array.end.textproto" + } + }, + "name": "meta.structure.array.textproto", + "patterns": [ + { + "include": "#comments" }, - "2": { - "name": "support.type.prototext" + { + "include": "#value" + }, + { + "match": ",", + "name": "punctuation.separator.array.textproto" }, - "3": { - "name": "punctuation.separator.key-value.prototext" + { + "match": "[^\\s\\]]", + "name": "invalid.illegal.expected-array-separator.textproto" + } + ] + }, + "object": { + "begin": "\\{", + "beginCaptures": { + "0": { + "name": "punctuation.definition.dictionary.begin.textproto" } }, "end": "\\}", "endCaptures": { "0": { - "name": "punctuation.terminator.prototext" + "name": "punctuation.definition.dictionary.end.textproto" } }, - "contentName": "meta.syntax.value.prototext", + "name": "meta.structure.dictionary.textproto", "patterns": [ { - "include": "#kv-pair" + "include": "#comments" + }, + { + "include": "#string-single" + }, + { + "include": "#string-double" + }, + { + "include": "#key" }, { - "include": "#dictionary" + "include": "#optional-key" }, { - "include": "#comment" + "include": "#field" } ] }, - "comment": { + "comments": { + "begin": "(^\\s+)?(?=#)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.textproto" + } + }, + "end": "(?!\\G)", + "endCaptures": { + "1": { + "name": "punctuation.whitespace.comment.trailing.textproto" + } + }, "patterns": [ { - "name": "comment.line.number-sign.prototext", - "match": "#.*" + "begin": "#", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.textproto" + } + }, + "end": "$", + "name": "comment.line.number-sign.textproto" } ] }, - "kv-pair": { - "name": "meta.dictionary.pair.prototext", - "begin": "\\b(?:([a-zA-Z]+[a-zA-Z0-9_]*)|([0-9]+))\\s*(:)\\s*", + "constant": { + "patterns": [ + { + "match": "\\b(?:true|false|null|Infinity|NaN)\\b", + "name": "constant.language.textproto" + }, + { + "match": "\\b[A-Z]+[A-Z0-9]*(?:_[A-Z0-9]+)*\\b", + "name": "variable.other.readonly.textproto" + } + ] + }, + "heredoc": { + "begin": "(<<)\\s*([_a-zA-Z]+)\\s*$", "beginCaptures": { "1": { - "name": "keyword.syntax.prototext" + "name": "keyword.operator.heredoc.textproto" }, "2": { - "name": "keyword.syntax.prototext" + "name": "keyword.control.heredoc-token.textproto" + } + }, + "end": "^\\s*(\\2)\\s*$", + "endCaptures": { + "1": { + "name": "keyword.control.heredoc-token.textproto" + } + }, + "name": "string.unquoted.heredoc.no-indent.textproto" + }, + "infinity": { + "match": "(-)*\\b(?:Infinity|NaN)\\b", + "name": "constant.language.textproto" + }, + "number": { + "patterns": [ + { + "comment": "handles hexadecimal numbers", + "match": "(0x)[0-9a-fA-f]*", + "name": "constant.numeric.hex.textproto" }, - "3": { - "name": "punctuation.separator.key-value.prototext" + { + "comment": "handles integer and decimal numbers", + "match": "[+-.]?(?=[1-9]|0(?!\\d))\\d+(\\.\\d+)?([eE][+-]?\\d+)?", + "name": "constant.numeric.textproto" + } + ] + }, + "string-double": { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.textproto" } }, - "end": "\\n", + "end": "\"", "endCaptures": { "0": { - "name": "punctuation.terminator.prototext" + "name": "punctuation.definition.string.end.textproto" } }, - "contentName": "meta.syntax.value.prototext", + "name": "string.quoted.double.textproto", "patterns": [ - { - "include": "#qstring-single" - }, { - "include": "#qstring-double" + "match": "(?x:\\\\(?:[\"\\\\/bfnrt]|u[0-9a-fA-F]{4}))", + "name": "constant.character.escape.textproto" }, { - "include": "#numeric" - }, + "match": "\\\\.", + "name": "invalid.illegal.unrecognized-string-escape.textproto" + } + ] + }, + "string-single": { + "begin": "'", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.textproto" + } + }, + "end": "'", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.textproto" + } + }, + "name": "string.quoted.single.textproto", + "patterns": [ { - "include": "#boolean" + "match": "(?x:\\\\(?:[\\'\\\\/bfnrt]|u[0-9a-fA-F]{4}))", + "name": "constant.character.escape.textproto" }, { - "include": "#enum" + "match": "\\\\.", + "name": "invalid.illegal.unrecognized-string-escape.textproto" + } + ] + }, + "key": { + "begin": "[a-zA-Z0-9_\\.-]+(\\s+)", + "beginCaptures": { + "0": { + "name": "entity.name.textproto meta.structure.dictionary.value.textproto" }, + "1": { + "name": "punctuation.separator.dictionary.key-value.textproto" + } + }, + "end": "\\n", + "name": "support.type.property-name.textproto", + "patterns": [ { - "include": "#comment" + "include": "#value" } ] }, - "boolean": { - "name": "constant.language.boolean.prototext", - "match": "(true)|(false)" - }, - "qstring-single": { - "name": "string.quoted.single.prototext", - "match": "'(?:\\\\x[0-9a-f]{2}|\\\\[0-7]{3}|\\\\[0-7]|\\\\[abfnrtv\\\\\\?'\"]|[^'\\0\\n\\\\])*'" - }, - "qstring-double": { - "name": "string.quoted.double.prototext", - "match": "\"(?:\\\\x[0-9a-f]{2}|\\\\[0-7]{3}|\\\\[0-7]|\\\\[abfnrtv\\\\\\?'\"]|[^\"\\0\\n\\\\])*\"" + "optional-key": { + "begin": "\\[[a-zA-Z0-9_\\.-]+\\](\\s+)", + "beginCaptures": { + "0": { + "name": "entity.name.textproto meta.structure.dictionary.value.textproto" + }, + "1": { + "name": "punctuation.separator.dictionary.key-value.textproto" + } + }, + "end": "\\n", + "name": "support.type.property-name.textproto", + "patterns": [ + { + "include": "#value" + } + ] }, - "enum": { - "name": "entity.name.type.enum.proto", - "match": "(\\b[A-Z][a-zA-Z0-9_]*\\b)" + "field": { + "begin": "\\[?[a-zA-Z0-9_\\.-]+\\]?(:)", + "beginCaptures": { + "0": { + "name": "variable.textproto meta.structure.dictionary.value.textproto" + }, + "1": { + "name": "punctuation.separator.dictionary.key-value.textproto" + } + }, + "end": "\\n", + "name": "support.type.property-name.textproto", + "patterns": [ + { + "include": "#value" + } + ] }, - "numeric": { - "name": "constant.numeric.prototext", - "match": "[0-9]+" + "value": { + "patterns": [ + { + "include": "#constant" + }, + { + "include": "#infinity" + }, + { + "include": "#number" + }, + { + "include": "#string-double" + }, + { + "include": "#string-single" + }, + { + "include": "#heredoc" + }, + { + "include": "#array" + }, + { + "include": "#object" + } + ] } - }, - "scopeName": "source.prototext" -} + } +} \ No newline at end of file