func Parse(filename string, r io.Reader) ([]*Group, error) {

	n := 0
	groups := make([]*Group, 0)
	scanner := bufio.NewScanner(r)

	// whether we're at the point of expectations or
	// not.
	settingExpectations := false

	var currentGroup *Group
	var currentRequest *Request

	for scanner.Scan() {
		n++
		line, err := ParseLine(n, scanner.Bytes())
		if err != nil {
			return nil, err
		}
		switch line.Type {
		case LineTypeGroupHeading:
			// new group
			if currentGroup != nil {
				if currentRequest != nil {
					currentGroup.Requests = append(currentGroup.Requests, currentRequest)
					currentRequest = nil
				}
				groups = append(groups, currentGroup)
			}
			title, err := getok(line.Regexp.FindSubmatch(line.Bytes), 1)
			if err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			currentGroup = &Group{
				Filename: filename,
				Title:    title,
			}
		case LineTypeRequest:
			// new request
			if currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errMissingGroupHeader}
			}
			if currentRequest != nil {
				currentGroup.Requests = append(currentGroup.Requests, currentRequest)
			}
			settingExpectations = false
			var err error
			currentRequest = &Request{}
			matches := line.Regexp.FindSubmatch(line.Bytes)
			if currentRequest.Method, err = getok(matches, 1); err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			if currentRequest.Path, err = getok(matches, 2); err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
		case LineTypeCodeBlock:

			if currentRequest == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedCodeblock}
			}

			var bodyType string
			if len(line.Bytes) > 3 {
				bodyType = string(line.Bytes[3:])
			}

			var lines Lines
			var err error
			n, lines, err = scancodeblock(n, scanner)
			if err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			if settingExpectations {
				currentRequest.ExpectedBody = lines
				currentRequest.ExpectedBodyType = bodyType
			} else {
				currentRequest.Body = lines
				currentRequest.BodyType = bodyType
			}

		case LineTypeDetail:
			if currentRequest == nil && currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedDetails}
			}
			if currentRequest == nil {
				currentGroup.Details = append(currentGroup.Details, line)
				continue
			}
			if settingExpectations {
				currentRequest.ExpectedDetails = append(currentRequest.ExpectedDetails, line)
			} else {
				currentRequest.Details = append(currentRequest.Details, line)
			}
		case LineTypeParam:
			if currentRequest == nil && currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedParams}
			}
			if settingExpectations {
				return nil, &ErrLine{N: n, Err: errUnexpectedParams}
			}
			currentRequest.Params = append(currentRequest.Params, line)
		case LineTypeSeparator:
			settingExpectations = true
		}

	}

	if currentGroup == nil {
		return nil, &ErrLine{N: n, Err: errMissingGroupHeader}
	}
	if currentRequest != nil {
		currentGroup.Requests = append(currentGroup.Requests, currentRequest)
	}
	groups = append(groups, currentGroup)

	return groups, nil
}
func Parse(filename string, r io.Reader) ([]*Group, error) {

	n := 0
	groups := make([]*Group, 0)
	scanner := bufio.NewScanner(r)

	
	
	settingExpectations := false

	var currentGroup *Group
	var currentRequest *Request

	for scanner.Scan() {
		n++
		line, err := ParseLine(n, scanner.Bytes())
		if err != nil {
			return nil, err
		}
		switch line.Type {
		case LineTypeGroupHeading:
			
			if currentGroup != nil {
				if currentRequest != nil {
					currentGroup.Requests = append(currentGroup.Requests, currentRequest)
					currentRequest = nil
				}
				groups = append(groups, currentGroup)
			}
			title, err := getok(line.Regexp.FindSubmatch(line.Bytes), 1)
			if err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			currentGroup = &Group{
				Filename: filename,
				Title:    title,
			}
		case LineTypeRequest:
			
			if currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errMissingGroupHeader}
			}
			if currentRequest != nil {
				currentGroup.Requests = append(currentGroup.Requests, currentRequest)
			}
			settingExpectations = false
			var err error
			currentRequest = &Request{}
			matches := line.Regexp.FindSubmatch(line.Bytes)
			if currentRequest.Method, err = getok(matches, 1); err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			if currentRequest.Path, err = getok(matches, 2); err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
		case LineTypeCodeBlock:

			if currentRequest == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedCodeblock}
			}

			var bodyType string
			if len(line.Bytes) > 3 {
				bodyType = string(line.Bytes[3:])
			}

			var lines Lines
			var err error
			n, lines, err = scancodeblock(n, scanner)
			if err != nil {
				return nil, &ErrLine{N: n, Err: err}
			}
			if settingExpectations {
				currentRequest.ExpectedBody = lines
				currentRequest.ExpectedBodyType = bodyType
			} else {
				currentRequest.Body = lines
				currentRequest.BodyType = bodyType
			}

		case LineTypeDetail:
			if currentRequest == nil && currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedDetails}
			}
			if currentRequest == nil {
				currentGroup.Details = append(currentGroup.Details, line)
				continue
			}
			if settingExpectations {
				currentRequest.ExpectedDetails = append(currentRequest.ExpectedDetails, line)
			} else {
				currentRequest.Details = append(currentRequest.Details, line)
			}
		case LineTypeParam:
			if currentRequest == nil && currentGroup == nil {
				return nil, &ErrLine{N: n, Err: errUnexpectedParams}
			}
			if settingExpectations {
				return nil, &ErrLine{N: n, Err: errUnexpectedParams}
			}
			currentRequest.Params = append(currentRequest.Params, line)
		case LineTypeSeparator:
			settingExpectations = true
		}

	}

	if currentGroup == nil {
		return nil, &ErrLine{N: n, Err: errMissingGroupHeader}
	}
	if currentRequest != nil {
		currentGroup.Requests = append(currentGroup.Requests, currentRequest)
	}
	groups = append(groups, currentGroup)

	return groups, nil
}
func Parse ( filename string , r io . Reader ) ( [ ] * Group , error ) { n := 0 groups := make ( [ ] * Group , 0 ) scanner := bufio . NewScanner ( r ) // whether we're at the point of expectations or // not. settingExpectations := false var currentGroup * Group var currentRequest * Request for scanner . Scan ( ) { n ++ line , err := ParseLine ( n , scanner . Bytes ( ) ) if err != nil { return nil , err } switch line . Type { case LineTypeGroupHeading : // new group if currentGroup != nil { if currentRequest != nil { currentGroup . Requests = append ( currentGroup . Requests , currentRequest ) currentRequest = nil } groups = append ( groups , currentGroup ) } title , err := getok ( line . Regexp . FindSubmatch ( line . Bytes ) , 1 ) if err != nil { return nil , & ErrLine { N : n , Err : err } } currentGroup = & Group { Filename : filename , Title : title , } case LineTypeRequest : // new request if currentGroup == nil { return nil , & ErrLine { N : n , Err : errMissingGroupHeader } } if currentRequest != nil { currentGroup . Requests = append ( currentGroup . Requests , currentRequest ) } settingExpectations = false var err error currentRequest = & Request { } matches := line . Regexp . FindSubmatch ( line . Bytes ) if currentRequest . Method , err = getok ( matches , 1 ) ; err != nil { return nil , & ErrLine { N : n , Err : err } } if currentRequest . Path , err = getok ( matches , 2 ) ; err != nil { return nil , & ErrLine { N : n , Err : err } } case LineTypeCodeBlock : if currentRequest == nil { return nil , & ErrLine { N : n , Err : errUnexpectedCodeblock } } var bodyType string if len ( line . Bytes ) > 3 { bodyType = string ( line . Bytes [ 3 : ] ) } var lines Lines var err error n , lines , err = scancodeblock ( n , scanner ) if err != nil { return nil , & ErrLine { N : n , Err : err } } if settingExpectations { currentRequest . ExpectedBody = lines currentRequest . ExpectedBodyType = bodyType } else { currentRequest . Body = lines currentRequest . BodyType = bodyType } case LineTypeDetail : if currentRequest == nil && currentGroup == nil { return nil , & ErrLine { N : n , Err : errUnexpectedDetails } } if currentRequest == nil { currentGroup . Details = append ( currentGroup . Details , line ) continue } if settingExpectations { currentRequest . ExpectedDetails = append ( currentRequest . ExpectedDetails , line ) } else { currentRequest . Details = append ( currentRequest . Details , line ) } case LineTypeParam : if currentRequest == nil && currentGroup == nil { return nil , & ErrLine { N : n , Err : errUnexpectedParams } } if settingExpectations { return nil , & ErrLine { N : n , Err : errUnexpectedParams } } currentRequest . Params = append ( currentRequest . Params , line ) case LineTypeSeparator : settingExpectations = true } } if currentGroup == nil { return nil , & ErrLine { N : n , Err : errMissingGroupHeader } } if currentRequest != nil { currentGroup . Requests = append ( currentGroup . Requests , currentRequest ) } groups = append ( groups , currentGroup ) return groups , nil }
// Parse parses a file.
Parse parses a file .