func (p *parser) readExtension(ext *ast.Extension) *parseError { if err := p.readToken("extend"); err != nil { return err } ext.Position = p.cur.astPosition() tok := p.next() if tok.err != nil { return tok.err } ext.Extendee = tok.value // checked during resolution if err := p.readToken("{"); err != nil { return err } for !p.done { tok := p.next() if tok.err != nil { return tok.err } if tok.value == "}" { // end of extension return nil } p.back() field := new(ast.Field) ext.Fields = append(ext.Fields, field) field.Up = ext // p.readFile uses this if err := p.readField(field); err != nil { return err } } return p.errorf("unexpected EOF while parsing extension") }
func (p *parser) readMessageContents(msg *ast.Message) *parseError { // Parse message fields and other things inside a message. var oneof *ast.Oneof // set while inside a oneof for !p.done { tok := p.next() if tok.err != nil { return tok.err } switch tok.value { case "extend": // extension p.back() ext := new(ast.Extension) msg.Extensions = append(msg.Extensions, ext) if err := p.readExtension(ext); err != nil { return err } ext.Up = msg case "oneof": // oneof if oneof != nil { return p.errorf("nested oneof not permitted") } oneof = new(ast.Oneof) msg.Oneofs = append(msg.Oneofs, oneof) oneof.Position = p.cur.astPosition() tok := p.next() if tok.err != nil { return tok.err } oneof.Name = tok.value // TODO: validate oneof.Up = msg if err := p.readToken("{"); err != nil { return err } case "message": // nested message p.back() nmsg := new(ast.Message) msg.Messages = append(msg.Messages, nmsg) if err := p.readMessage(nmsg); err != nil { return err } nmsg.Up = msg case "enum": // nested enum p.back() ne := new(ast.Enum) msg.Enums = append(msg.Enums, ne) if err := p.readEnum(ne); err != nil { return err } ne.Up = msg case "extensions": // extension range p.back() r, err := p.readExtensionRange() if err != nil { return err } msg.ExtensionRanges = append(msg.ExtensionRanges, r...) default: // field; this token is required/optional/repeated, // a primitive type, or a named type. p.back() field := new(ast.Field) msg.Fields = append(msg.Fields, field) field.Oneof = oneof field.Up = msg // p.readField uses this if err := p.readField(field); err != nil { return err } case "}": if oneof != nil { // end of oneof oneof = nil continue } // end of message p.back() return nil } } return p.errorf("unexpected EOF while parsing message") }