Joe Tsai | 21ade49 | 2019-05-22 13:42:54 -0400 | [diff] [blame^] | 1 | // Copyright 2019 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package impl |
| 6 | |
| 7 | import ( |
| 8 | "google.golang.org/protobuf/internal/encoding/wire" |
| 9 | "google.golang.org/protobuf/internal/fieldnum" |
| 10 | ) |
| 11 | |
| 12 | // To avoid a dependency from legacy to descriptor.proto, use a hand-written parser |
| 13 | // for the bits of the descriptor we need. |
| 14 | // |
| 15 | // TODO: Consider unifying this with the parser in fileinit. |
| 16 | |
| 17 | type legacyFileDescriptorProto struct { |
| 18 | Syntax string |
| 19 | Package string |
| 20 | EnumType []*legacyEnumDescriptorProto |
| 21 | MessageType []*legacyDescriptorProto |
| 22 | } |
| 23 | |
| 24 | func (fd legacyFileDescriptorProto) GetSyntax() string { return fd.Syntax } |
| 25 | func (fd legacyFileDescriptorProto) GetPackage() string { return fd.Package } |
| 26 | |
| 27 | func legacyParseFileDescProto(b []byte) *legacyFileDescriptorProto { |
| 28 | fd := &legacyFileDescriptorProto{} |
| 29 | for len(b) > 0 { |
| 30 | num, typ, n := wire.ConsumeTag(b) |
| 31 | legacyParseCheck(n) |
| 32 | b = b[n:] |
| 33 | switch typ { |
| 34 | case wire.BytesType: |
| 35 | v, n := wire.ConsumeBytes(b) |
| 36 | b = b[n:] |
| 37 | switch num { |
| 38 | case fieldnum.FileDescriptorProto_Syntax: |
| 39 | fd.Syntax = string(v) |
| 40 | case fieldnum.FileDescriptorProto_Package: |
| 41 | fd.Package = string(v) |
| 42 | case fieldnum.FileDescriptorProto_EnumType: |
| 43 | fd.EnumType = append(fd.EnumType, legacyParseEnumDescProto(v)) |
| 44 | case fieldnum.FileDescriptorProto_MessageType: |
| 45 | fd.MessageType = append(fd.MessageType, parseDescProto(v)) |
| 46 | } |
| 47 | default: |
| 48 | n := wire.ConsumeFieldValue(num, typ, b) |
| 49 | legacyParseCheck(n) |
| 50 | b = b[n:] |
| 51 | } |
| 52 | } |
| 53 | return fd |
| 54 | } |
| 55 | |
| 56 | type legacyDescriptorProto struct { |
| 57 | Name string |
| 58 | NestedType []*legacyDescriptorProto |
| 59 | EnumType []*legacyEnumDescriptorProto |
| 60 | } |
| 61 | |
| 62 | func (md legacyDescriptorProto) GetName() string { return md.Name } |
| 63 | |
| 64 | func parseDescProto(b []byte) *legacyDescriptorProto { |
| 65 | md := &legacyDescriptorProto{} |
| 66 | for len(b) > 0 { |
| 67 | num, typ, n := wire.ConsumeTag(b) |
| 68 | legacyParseCheck(n) |
| 69 | b = b[n:] |
| 70 | switch typ { |
| 71 | case wire.BytesType: |
| 72 | v, n := wire.ConsumeBytes(b) |
| 73 | legacyParseCheck(n) |
| 74 | b = b[n:] |
| 75 | switch num { |
| 76 | case fieldnum.DescriptorProto_Name: |
| 77 | md.Name = string(v) |
| 78 | case fieldnum.DescriptorProto_NestedType: |
| 79 | md.NestedType = append(md.NestedType, parseDescProto(v)) |
| 80 | case fieldnum.DescriptorProto_EnumType: |
| 81 | md.EnumType = append(md.EnumType, legacyParseEnumDescProto(v)) |
| 82 | } |
| 83 | default: |
| 84 | n := wire.ConsumeFieldValue(num, typ, b) |
| 85 | legacyParseCheck(n) |
| 86 | b = b[n:] |
| 87 | } |
| 88 | } |
| 89 | return md |
| 90 | } |
| 91 | |
| 92 | type legacyEnumDescriptorProto struct { |
| 93 | Name string |
| 94 | Value []*legacyEnumValueDescriptorProto |
| 95 | } |
| 96 | |
| 97 | func (ed legacyEnumDescriptorProto) GetName() string { return ed.Name } |
| 98 | |
| 99 | func legacyParseEnumDescProto(b []byte) *legacyEnumDescriptorProto { |
| 100 | ed := &legacyEnumDescriptorProto{} |
| 101 | for len(b) > 0 { |
| 102 | num, typ, n := wire.ConsumeTag(b) |
| 103 | legacyParseCheck(n) |
| 104 | b = b[n:] |
| 105 | switch typ { |
| 106 | case wire.BytesType: |
| 107 | v, n := wire.ConsumeBytes(b) |
| 108 | legacyParseCheck(n) |
| 109 | b = b[n:] |
| 110 | switch num { |
| 111 | case fieldnum.EnumDescriptorProto_Name: |
| 112 | ed.Name = string(v) |
| 113 | case fieldnum.EnumDescriptorProto_Value: |
| 114 | ed.Value = append(ed.Value, legacyParseEnumValueDescProto(v)) |
| 115 | } |
| 116 | default: |
| 117 | n := wire.ConsumeFieldValue(num, typ, b) |
| 118 | legacyParseCheck(n) |
| 119 | b = b[n:] |
| 120 | } |
| 121 | } |
| 122 | return ed |
| 123 | } |
| 124 | |
| 125 | type legacyEnumValueDescriptorProto struct { |
| 126 | Name string |
| 127 | Number int32 |
| 128 | } |
| 129 | |
| 130 | func (ed legacyEnumValueDescriptorProto) GetName() string { return ed.Name } |
| 131 | func (ed legacyEnumValueDescriptorProto) GetNumber() int32 { return ed.Number } |
| 132 | |
| 133 | func legacyParseEnumValueDescProto(b []byte) *legacyEnumValueDescriptorProto { |
| 134 | vd := &legacyEnumValueDescriptorProto{} |
| 135 | for len(b) > 0 { |
| 136 | num, typ, n := wire.ConsumeTag(b) |
| 137 | legacyParseCheck(n) |
| 138 | b = b[n:] |
| 139 | switch typ { |
| 140 | case wire.VarintType: |
| 141 | v, n := wire.ConsumeVarint(b) |
| 142 | legacyParseCheck(n) |
| 143 | b = b[n:] |
| 144 | switch num { |
| 145 | case fieldnum.EnumValueDescriptorProto_Number: |
| 146 | vd.Number = int32(v) |
| 147 | } |
| 148 | case wire.BytesType: |
| 149 | v, n := wire.ConsumeBytes(b) |
| 150 | legacyParseCheck(n) |
| 151 | b = b[n:] |
| 152 | switch num { |
| 153 | case fieldnum.EnumDescriptorProto_Name: |
| 154 | vd.Name = string(v) |
| 155 | } |
| 156 | default: |
| 157 | n := wire.ConsumeFieldValue(num, typ, b) |
| 158 | legacyParseCheck(n) |
| 159 | b = b[n:] |
| 160 | } |
| 161 | } |
| 162 | return vd |
| 163 | } |
| 164 | |
| 165 | func legacyParseCheck(n int) { |
| 166 | if n < 0 { |
| 167 | panic(wire.ParseError(n)) |
| 168 | } |
| 169 | } |