oneof.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) 2017 Ernest Micklei
  2. //
  3. // MIT License
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the
  7. // "Software"), to deal in the Software without restriction, including
  8. // without limitation the rights to use, copy, modify, merge, publish,
  9. // distribute, sublicense, and/or sell copies of the Software, and to
  10. // permit persons to whom the Software is furnished to do so, subject to
  11. // the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. package proto
  24. import (
  25. "text/scanner"
  26. )
  27. // Oneof is a field alternate.
  28. type Oneof struct {
  29. Position scanner.Position
  30. Comment *Comment
  31. Name string
  32. Elements []Visitee
  33. Parent Visitee
  34. }
  35. // addElement is part of elementContainer
  36. func (o *Oneof) addElement(v Visitee) {
  37. v.parent(o)
  38. o.Elements = append(o.Elements, v)
  39. }
  40. // elements is part of elementContainer
  41. func (o *Oneof) elements() []Visitee {
  42. return o.Elements
  43. }
  44. // takeLastComment is part of elementContainer
  45. // removes and returns the last element of the list if it is a Comment.
  46. func (o *Oneof) takeLastComment(expectedOnLine int) (last *Comment) {
  47. last, o.Elements = takeLastCommentIfEndsOnLine(o.Elements, expectedOnLine)
  48. return last
  49. }
  50. // parse expects:
  51. // oneofName "{" { oneofField | emptyStatement } "}"
  52. func (o *Oneof) parse(p *Parser) error {
  53. pos, tok, lit := p.next()
  54. if tok != tIDENT {
  55. if !isKeyword(tok) {
  56. return p.unexpected(lit, "oneof identifier", o)
  57. }
  58. }
  59. o.Name = lit
  60. pos, tok, lit = p.next()
  61. if tok != tLEFTCURLY {
  62. return p.unexpected(lit, "oneof opening {", o)
  63. }
  64. for {
  65. pos, tok, lit = p.nextTypeName()
  66. switch tok {
  67. case tCOMMENT:
  68. if com := mergeOrReturnComment(o.elements(), lit, pos); com != nil { // not merged?
  69. o.addElement(com)
  70. }
  71. case tIDENT:
  72. f := newOneOfField()
  73. f.Position = pos
  74. f.Comment, o.Elements = takeLastCommentIfEndsOnLine(o.elements(), pos.Line-1) // TODO call takeLastComment instead?
  75. f.Type = lit
  76. if err := parseFieldAfterType(f.Field, p); err != nil {
  77. return err
  78. }
  79. o.addElement(f)
  80. case tGROUP:
  81. g := new(Group)
  82. g.Position = pos
  83. g.Comment, o.Elements = takeLastCommentIfEndsOnLine(o.elements(), pos.Line-1)
  84. if err := g.parse(p); err != nil {
  85. return err
  86. }
  87. o.addElement(g)
  88. case tOPTION:
  89. opt := new(Option)
  90. opt.Position = pos
  91. opt.Comment, o.Elements = takeLastCommentIfEndsOnLine(o.elements(), pos.Line-1)
  92. if err := opt.parse(p); err != nil {
  93. return err
  94. }
  95. o.addElement(opt)
  96. case tSEMICOLON:
  97. maybeScanInlineComment(p, o)
  98. // continue
  99. default:
  100. goto done
  101. }
  102. }
  103. done:
  104. if tok != tRIGHTCURLY {
  105. return p.unexpected(lit, "oneof closing }", o)
  106. }
  107. return nil
  108. }
  109. // Accept dispatches the call to the visitor.
  110. func (o *Oneof) Accept(v Visitor) {
  111. v.VisitOneof(o)
  112. }
  113. // OneOfField is part of Oneof.
  114. type OneOfField struct {
  115. *Field
  116. }
  117. func newOneOfField() *OneOfField { return &OneOfField{Field: new(Field)} }
  118. // Accept dispatches the call to the visitor.
  119. func (o *OneOfField) Accept(v Visitor) {
  120. v.VisitOneofField(o)
  121. }
  122. // Doc is part of Documented
  123. // Note: although Doc() is defined on Field, it must be implemented here as well.
  124. func (o *OneOfField) Doc() *Comment {
  125. return o.Comment
  126. }
  127. func (o *Oneof) parent(v Visitee) { o.Parent = v }