Grammar
Grammar
represents the custom grammar for the next files.
The grammar is used to define a subset of the next files. It can limit the features of the next code according by your requirements. The grammar is a yaml file that contains rules.
Here is an example of the grammar file:
- YAML
- JSON
struct:
annotations:
- name: message
description: Sets the declaration as a message.
parameters:
- name: type
types: [int]
description: Sets the message type id
required: true
validators:
- name: MessageTypeMustBePositive
message: must be positive
expression: '{{gt . 0}}'
- name: req
types: [bool]
description: Sets the message as a request.
{
"struct": {
"annotations": [{
"name": "message",
"description": "Sets the declaration as a message.",
"parameters": [{
"name": "type",
"types": ["int"],
"description": "Sets the message type id",
"required": true,
"validators": [{
"name": "MessageTypeMustBePositive",
"message": "must be positive",
"expression": "{{gt . 0}}"
}]
},
{
"name": "req",
"types": ["bool"],
"description": "Sets the message as a request."
}]
}]
}
}
It extends built-in grammar and defines a @message
annotation for struct
objects. For example:
package demo;
@message(type=1, req)
struct LoginRequest {/*...*/}
@message(type=2)
struct LoginResponse {/*...*/}
Run the following command to show the built-in grammar:
next grammar
# Or outputs the grammar to a file
next grammar grammar.yaml
next grammar grammar.json
Builtin
Builtin
represents the built-in grammar rules. Here is an example source code for demonstration built-in grammar rules:
@next(
// available is used to set the available expression for the file.
available="cpp|java",
// deprecated is used to set the declaration as deprecated.
deprecated,
// tokens is used to set the space separated tokens for the declaration name.
tokens="DB",
// <LANG>_package is used to set the package name for target languages.
cpp_package="db",
java_package="com.example.db",
// <LANG>_imports is used to set the import declarations for target languages.
cpp_imports="<iostream>",
)
package db;
@next(
available="cpp",
deprecated,
tokens="HTTP Version",
)
const int HTTPVersion = 2;
@next(
available="cpp|java",
deprecated,
tokens="HTTP Method",
// <LANG>_alias is used to set the alias name for target languages.
java_alias="org.springframework.http.HttpMethod",
)
enum HTTPMethod {
Get = "GET",
Post = "POST",
Put = "PUT",
Delete = "DELETE",
Head = "HEAD",
Options = "OPTIONS",
Patch = "PATCH",
Trace = "TRACE",
@next(available="!java", deprecated, tokens="Connect")
Connect = "CONNECT",
}
@next(
available="cpp|java",
deprecated,
tokens="User",
cpp_alias="model::User",
)
struct User {
int id;
@next(
available="!java",
deprecated,
tokens="Name",
optional,
default="John Doe",
cpp_alias="std::string",
)
string name;
}
@next(
available="cpp|java",
deprecated,
tokens="User Repository",
prompt="Prompt for AGI.",
java_alias="org.springframework.data.repository.CrudRepository<User, Long>",
)
interface UserRepository {
@next(
available="!java",
deprecated,
tokens="Get User",
mut,
error,
cpp_alias="std::shared_ptr<model::User>",
prompt="Prompt for AGI.",
)
findById(
@next(available="!java", deprecated, tokens="ID", mut, cpp_alias="int64_t")
int64 id
) User;
}
Common
Annotation
Annotation
represents the annotation grammar rules. Only the built-in annotations are supported if no annotations are defined in the grammar.
Example:
- YAML
- JSON
{
"struct": {
"annotations": [
{
"name": "message",
"description": "Sets the struct as a message.",
"parameters": [
{
"name": "type",
"description": "Sets the message type id.",
"type": "int",
"required": true
"validators": [
{
"name": "MessageTypeMustBePositive",
"expression": "{{gt . 0}}",
"message": "message type must be positive"
}
]
}
]
}
]
}
}
struct:
annotations:
- name: message
description: Sets the struct as a message.
parameters:
- name: type
description: Sets the message type id.
types: [int]
required: true
validators:
- name: MessageTypeMustBePositive
expression: "{{gt . 0}}"
message: message type must be positive
package demo;
// Good
@message(type=1)
struct User {
int id;
string name;
}
@message
struct User {
int id;
string name;
}
// Error: message type is required
@message(type)
struct User {
int id;
string name;
}
// Error: message type must be an integer
@message(type=-1)
struct User {
int id;
string name;
}
// Error: message type must be positive
.Description
.Description
represents the annotation description.
.Name
.Name
represents the annotation name.
.Parameters
.Parameters
represents the annotation parameters.
.Validators
.Validators
represents the Validator for the annotation.
AnnotationParameter
AnnotationParameter
represents the annotation parameter grammar rules. If no parameters are defined, the annotation does not have any parameters.
.Description
.Description
represents the parameter description.
.Name
.Name
represents the parameter name pattern. The name pattern is a regular expression that can be used to match the annotation parameter name.
Example:
- "type": matches the annotation name
type
- "x|y": matches the annotation name
x
ory
- ".+_package": matches the annotation name that ends with
_package
, for example,cpp_package
,java_package
, etc.
.Required
.Required
represents the parameter is required or not.
.Types
.Types
represents the parameter type. The type is a string that can be one of the following types:
- bool: boolean type, the value can be
true
orfalse
- int: integer type, the value can be a positive or negative integer, for example,
123
- float: float type, the value can be a positive or negative float, for example,
1.23
- string: string type, the value can be a string, for example,
"hello"
- type: any type name, for example,
int
,float
,string
, etc. Custom type names are supported.
.Validators
.Validators
represents the Validator for the annotation parameter.
Annotations
Annotations
represents a list of annotations.
Validator
Validator
represents the validator for the grammar rules.
.Expression
.Expression
represents the validator expression. The expression is a template string that can access the data by the .
operator. The expression must return a boolean value.
The data is the current context object. For example, package object for the package validator.
.Message
.Message
represents the error message when the validator is failed.
.Name
.Name
represents the validator name.
Const
Const
represents the grammar rules for the const declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the const declaration.
.Disabled
.Disabled
represents the const declaration is off or not. If the const declaration is off, the const declaration is not allowed in the next files.
Example:
- YAML
- JSON
{
"const": {
"disabled": true
}
}
const:
disabled: true
package demo;
const x = 1;
// Error: const declaration is not allowed
.Types
.Types
represents a list of type names that are supported in the const declaration. If no types are defined, the const declaration supports all types. Otherwise, the const declaration only supports the specified types.
Currently, each type name can be one of the following types:
- bool: boolean type, the value can be
true
orfalse
- int: integer type, the value can be a positive or negative integer, for example,
123
- float: float type, the value can be a positive or negative float, for example,
1.23
- string: string type, the value can be a string, for example,
"hello"
Example:
- YAML
- JSON
{
"const": {
"types": ["int", "float"]
}
}
const:
types:
- int
- float
package demo;
const x = 1; // Good
const y = 1.23; // Good
const z = "hello";
// Error: string type is not allowed in the const declaration
.Validators
.Validators
represents the Validator for the const declaration. It's used to validate the const name. You can access the const name by .Name
.
Example:
- YAML
- JSON
{
"const": {
"validators": [
{
"name": "ConstNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "const name must be capitalized"
}
]
}
}
const:
validators:
- name: ConstNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: const name must be capitalized
package demo;
const Hello = 1; // Good
const world = 1;
// Error: const name must be capitalized, expected: World
Enum
Enum
represents the grammar rules for the enum declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the enum declaration.
.Disabled
.Disabled
represents the enum declaration is off or not. If the enum declaration is off, the enum declaration is not allowed in the next files.
Example:
- YAML
- JSON
{
"enum": {
"disabled": true
}
}
enum:
disabled: true
package demo;
enum Color {
Red;
Green;
Blue;
}
// Error: enum declaration is not allowed
.Member
.Member
represents the EnumMember grammar rules for the enum declaration.
.Validators
.Validators
represents the Validator for the enum declaration. It's used to validate the enum name. You can access the enum name by .Name
.
Example:
- YAML
- JSON
{
"enum": {
"validators": [
{
"name": "EnumNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "enum name must be capitalized"
}
]
}
}
enum:
validators:
- name: EnumNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: enum name must be capitalized
package demo;
// Good
enum Color {
Red;
Green;
Blue;
}
enum size {
Small;
Medium;
Large;
}
// Error: enum name must be capitalized, expected: Size
EnumMember
EnumMember
represents the grammar rules for the enum member declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the enum member declaration.
.Types
.Types
represents a list of type names that are supported in the enum declaration.
If no types are defined, the enum declaration supports all types. Otherwise, the enum declaration only supports the specified types.
Currently, each type name can be one of the following types:
- int: integer type, the value can be a positive or negative integer, for example,
123
- float: float type, the value can be a positive or negative float, for example,
1.23
- string: string type, the value can be a string, for example,
"hello"
Example:
- YAML
- JSON
{
"enum": {
"member": {
"types": ["int"]
}
}
}
enum:
member:
types:
- int
package demo;
// Good
enum Color {
Red = 1,
Green = 2,
Blue = 3
}
enum Size {
Small = "small",
Medium = "medium",
Large = "large"
}
// Error: string type is not allowed in the enum declaration
.Validators
.Validators
represents the Validator for the enum member declaration.
It's used to validate the enum member name. You can access the enum member name by .Name
.
Example:
- YAML
- JSON
{
"enum": {
"member": {
"validators": [
{
"name": "EnumMemberNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "enum member name must be capitalized"
}
]
}
}
}
enum:
member:
validators:
- name: EnumMemberNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: enum member name must be capitalized
package demo;
enum Size {
Small = 1,
Medium = 2,
large = 3;
// Error: enum member name must be capitalized, expected: Large
}
.ValueRequired
.ValueRequired
represents the enum member value is required or not. If the enum member value is required, the enum member value must be specified in the next files.
Example:
- YAML
- JSON
{
"enum": {
"member": {
"value_required": true
}
}
}
enum:
member:
value_required: true
package demo;
enum Size {
Small = 1,
Medium = 2;
Large;
// Error: enum member value is required
}
.ZeroRequired
.ZeroRequired
represents the enum member zero value for integer types is required or not.
If the enum member zero value is required, the enum member zero value must be specified in the next files.
Example:
- YAML
- JSON
{
"enum": {
"member": {
"zero_required": true
}
}
}
enum:
member:
zero_required: true
package demo;
enum Size {
Small = 1,
Medium = 2,
Large = 3;
}
// Error: enum member zero value is required, for example:
// enum Size {
// Small = 0,
// Medium = 1,
// Large = 2
// }
Import
Import
represents the grammar rules for the import declaration.
.Disabled
.Disabled
represents the import declaration is off or not. If the import declaration is off, the import declaration is not allowed in the next files.
Example:
- YAML
- JSON
{
"import": {
"disabled": true
}
}
import:
disabled: true
package demo;
import "other.next";
// Error: import declaration is not allowed
Interface
Interface
represents the grammar rules for the interface declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the interface declaration.
.Disabled
.Disabled
represents the interface declaration is off or not. If the interface declaration is off, the interface declaration is not allowed in the next files.
Example:
- YAML
- JSON
{
"interface": {
"disabled": true
}
}
interface:
disabled: true
package demo;
interface User {
GetID() int;
}
// Error: interface declaration is not allowed
.Method
.Method
represents the InterfaceMethod grammar rules for the interface declaration.
.Validators
.Validators
represents the Validator for the interface declaration. It's used to validate the interface name. You can access the interface name by .Name
.
Example:
- YAML
- JSON
{
"interface": {
"validators": [
{
"name": "InterfaceNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "interface name must be capitalized"
}
]
}
}
interface:
validators:
- name: InterfaceNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: interface name must be capitalized
package demo;
// Good
interface User {
GetID() int;
}
interface user {
GetName() string;
}
// Error: interface name must be capitalized, expected: User
InterfaceMethod
InterfaceMethod
represents the grammar rules for the interface method declaration.
Example:
- YAML
- JSON
{
"interface": {
"method": {
"annotations": [
{
"name": "http",
"description": "Sets the method as an HTTP handler.",
"parameters": [
{
"name": "method",
"description": "Sets the HTTP method.",
"type": "string",
"required": true
"validators": [
{
"name": "HTTPMethodMustBeValid",
"expression": "{{includes (list `GET` `POST` `PUT` `DELETE` `PATCH` `HEAD` `OPTIONS` `TRACE` `CONNECT`) .}}",
"message": "http method must be valid"
}
]
}
]
}
],
"validators": [
{
"name": "MethodNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "method name must be capitalized"
}
]
}
}
}
interface:
method:
annotations:
- name: http
description: Sets the method as an HTTP handler.
parameters:
- name: method
description: Sets the HTTP method.
types: [string]
required: true
validators:
- name: HTTPMethodMustBeValid
expression: "{{includes (list `GET` `POST` `PUT` `DELETE` `PATCH` `HEAD` `OPTIONS` `TRACE` `CONNECT`) .}}"
message: http method must be valid
validators:
- name: MethodNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: method name must be capitalized
.Annotations
.Annotations
represents the Annotation grammar rules for the interface method declaration.
.Parameter
.Parameter
represents the InterfaceMethodParameter grammar rules for the interface method declaration.
.Validators
.Validators
represents the Validator for the interface method declaration.
InterfaceMethodParameter
InterfaceMethodParameter
represents the grammar rules for the interface method parameter declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the interface method parameter declaration.
.Validators
.Validators
represents the Validator for the interface method parameter declaration.
Package
Package
represents the grammar rules for the package declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the package declaration.
.Validators
.Validators
represents the Validator for the package declaration. It's used to validate the package name. For example, You can limit the package name must be not start with a "_" character. The validator expression is a template string that can access package name by .Name
.
Example:
- YAML
- JSON
{
"package": {
"validators": [
{
"name": "PackageNameNotStartWithUnderscore",
"expression": "{{not (hasPrefix `_` .Name)}}",
"message": "package name must not start with an underscore"
}
]
}
}
package:
validators:
- name: PackageNameNotStartWithUnderscore
expression: "{{not (hasPrefix `_` .Name)}}"
message: package name must not start with an underscore
package _test;
// Error: package name must not start with an underscore
Struct
Struct
represents the grammar rules for the struct declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the struct declaration.
.Disabled
.Disabled
represents the struct declaration is off or not. If the struct declaration is off, the struct declaration is not allowed in the next files.
Example:
- YAML
- JSON
{
"struct": {
"disabled": true
}
}
struct:
disabled: true
package demo;
struct User {
int id;
string name;
}
// Error: struct declaration is not allowed
.Field
.Field
represents the StructField grammar rules for the struct declaration.
.Validators
.Validators
represents the Validator for the struct declaration. It's used to validate the struct name. You can access the struct name by .Name
.
Example:
- YAML
- JSON
{
"struct": {
"validators": [
{
"name": "StructNameMustBeCapitalized",
"expression": "{{eq .Name (.Name | capitalize)}}",
"message": "struct name must be capitalized"
}
]
}
}
struct:
validators:
- name: StructNameMustBeCapitalized
expression: "{{eq .Name (.Name | capitalize)}}"
message: struct name must be capitalized
package demo;
// Good
struct User {
int id;
string name;
}
struct point {
int x;
int y;
}
// Error: struct name must be capitalized, expected: Point
StructField
StructField
represents the grammar rules for the struct field declaration.
.Annotations
.Annotations
represents the Annotation grammar rules for the struct field declaration.
.Validators
.Validators
represents the Validator for the struct field declaration. It's used to validate the struct field name. You can access the struct field name by .Name
.
Example:
- YAML
- JSON
{
"struct": {
"field": {
"validators": [
{
"name": "StructFieldNameMustNotBeCapitalized",
"expression": "{{ne .Name (capitalize .Name)}}",
"message": "struct field name must not be capitalized"
}
]
}
}
}
struct:
field:
validators:
- name: StructFieldNameMustNotBeCapitalized
expression: "{{ne .Name (capitalize .Name)}}"
message: struct field name must not be capitalized
package demo;
struct User {
int id;
string Name;
// Error: struct field name must not be capitalized, expected: name
}