group.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. // Group represents a (proto2 only) group.
  28. // https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#group_field
  29. type Group struct {
  30. Position scanner.Position
  31. Comment *Comment
  32. Name string
  33. Optional bool
  34. Repeated bool
  35. Required bool
  36. Sequence int
  37. Elements []Visitee
  38. Parent Visitee
  39. }
  40. // Accept dispatches the call to the visitor.
  41. func (g *Group) Accept(v Visitor) {
  42. v.VisitGroup(g)
  43. }
  44. // addElement is part of elementContainer
  45. func (g *Group) addElement(v Visitee) {
  46. v.parent(g)
  47. g.Elements = append(g.Elements, v)
  48. }
  49. // elements is part of elementContainer
  50. func (g *Group) elements() []Visitee {
  51. return g.Elements
  52. }
  53. // Doc is part of Documented
  54. func (g *Group) Doc() *Comment {
  55. return g.Comment
  56. }
  57. // takeLastComment is part of elementContainer
  58. // removes and returns the last element of the list if it is a Comment.
  59. func (g *Group) takeLastComment(expectedOnLine int) (last *Comment) {
  60. last, g.Elements = takeLastCommentIfEndsOnLine(g.Elements, expectedOnLine)
  61. return
  62. }
  63. // parse expects:
  64. // groupName "=" fieldNumber { messageBody }
  65. func (g *Group) parse(p *Parser) (err error) {
  66. _, tok, lit := p.next()
  67. if tok != tIDENT {
  68. if !isKeyword(tok) {
  69. return p.unexpected(lit, "group name", g)
  70. }
  71. }
  72. g.Name = lit
  73. _, tok, lit = p.next()
  74. if tok != tEQUALS {
  75. return p.unexpected(lit, "group =", g)
  76. }
  77. var i int
  78. if i, err = p.nextInteger(); err != nil {
  79. return p.unexpected(lit, "group sequence number", g)
  80. }
  81. g.Sequence = i
  82. _, tok, lit = p.next()
  83. if tok != tLEFTCURLY {
  84. return p.unexpected(lit, "group opening {", g)
  85. }
  86. return parseMessageBody(p, g)
  87. }
  88. func (g *Group) parent(v Visitee) { g.Parent = v }