Skip to content

Commit

Permalink
Support comments in schema (dgraph-io#3133)
Browse files Browse the repository at this point in the history
* schema/state.go: add comment state to lexer

This adds comment detection to lexer. A comment starts with # and ends with
new line or EOF. When new line is detected, it's emitted so the caller can handle it.
If EOF is found, that should end further parsing.

* schema/parse_test.go: add test for comments in schema types

* gql/parser.go: fixed typo

* schema/state.go: rename func lexComment to lexTextComment

Package gql has another function called lexComment that works slightly
different to this one, so I renamed this one to avoid confusion.
  • Loading branch information
srfrog authored and dna2github committed Jul 19, 2019
1 parent b4f6c87 commit 57e29fe
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
2 changes: 1 addition & 1 deletion gql/parser.go
Expand Up @@ -948,7 +948,7 @@ func parseSchemaFields(it *lex.ItemIterator, s *pb.SchemaRequest) error {
return item.Errorf("Invalid schema block.")
}
}
return it.Errorf("Expecting } to end fields list, but none was found")
return it.Errorf("Expecting } to end fields list, but none was found")
}

func getSchema(it *lex.ItemIterator) (*pb.SchemaRequest, error) {
Expand Down
62 changes: 61 additions & 1 deletion schema/parse_test.go
Expand Up @@ -526,7 +526,7 @@ func TestParseScalarType(t *testing.T) {
type Person {
Name: string
Nickname: [String]
Alive: Bool
Alive: Bool
}
`)
require.NoError(t, err)
Expand Down Expand Up @@ -743,6 +743,66 @@ func TestParseTypeErrMissingType(t *testing.T) {
require.Contains(t, err.Error(), "Missing field type in type declaration")
}

func TestParseComments(t *testing.T) {
reset()
_, err := Parse(`
#
# This is a test
#
user: bool .
user.name: string @index(exact) . # this should be unique
user.email: string @index(exact) . # this should be unique and lower-cased
user.password: password .
user.code: string . # for password recovery (can be null)
node: bool .
node.hashid: string @index(exact) . # @username/hashid
node.owner: uid @reverse . # (can be null)
node.parent: uid . # [uid] (use facet)
node.xdata: string . # store custom json data
#
# End of test
#
`)
require.NoError(t, err)
}

func TestParseCommentsNoop(t *testing.T) {
reset()
_, err := Parse(`
# Spicy jalapeno bacon ipsum dolor amet t-bone kevin spare ribs sausage jowl cow pastrami short.
# Leberkas alcatra kielbasa chicken pastrami swine bresaola. Spare ribs landjaeger meatloaf.
# Chicken biltong boudin porchetta jowl swine burgdoggen cow kevin ground round landjaeger ham.
# Tongue buffalo cow filet mignon boudin sirloin pancetta pork belly beef ribs. Cow landjaeger.
`)
require.NoError(t, err)
}

func TestParseCommentsErrMissingType(t *testing.T) {
reset()
_, err := Parse(`
# The definition below should trigger an error
# because we commented out its type.
node: # bool .
`)
require.Error(t, err)
require.Contains(t, err.Error(), "Missing Type")
}

func TestParseTypeComments(t *testing.T) {
reset()
_, err := Parse(`
# User is a service user
type User {
# TODO: add more fields
Name: string # e.g., srfrog
# expanded comment
# embedded # comments # here
}
# /User
`)
require.NoError(t, err)
}

var ps *badger.DB

func TestMain(m *testing.M) {
Expand Down
21 changes: 21 additions & 0 deletions schema/state.go
Expand Up @@ -53,6 +53,8 @@ Loop:
l.Emit(itemNewLine)
case r == '.':
l.Emit(itemDot)
case r == '#':
return lexTextComment
case r == ',':
l.Emit(itemComma)
case r == '<':
Expand Down Expand Up @@ -105,6 +107,25 @@ func lexWord(l *lex.Lexer) lex.StateFn {
return lexText
}

// lexTextComment lexes a comment text inside a schema.
func lexTextComment(l *lex.Lexer) lex.StateFn {
for {
r := l.Next()
if r == lex.EOF {
l.Ignore()
l.Emit(lex.ItemEOF)
break
}
if !lex.IsEndOfLine(r) {
continue
}
l.Ignore()
l.Emit(itemNewLine)
break
}
return lexText
}

// isNameBegin returns true if the rune is an alphabet.
func isNameBegin(r rune) bool {
switch {
Expand Down

0 comments on commit 57e29fe

Please sign in to comment.