1 package main
2
3
14
15 import (
16 "log"
17 "strconv"
18 "strings"
19 )
20
21 func (xml *XML) Translate(parent *Protocol) *Protocol {
22 protocol := &Protocol{
23 Parent: parent,
24 Name: xml.Header,
25 ExtXName: xml.ExtensionXName,
26 ExtName: xml.ExtensionName,
27 MajorVersion: xml.MajorVersion,
28 MinorVersion: xml.MinorVersion,
29
30 Imports: make([]*Protocol, 0),
31 Types: make([]Type, 0),
32 Requests: make([]*Request, len(xml.Requests)),
33 }
34
35 for _, imp := range xml.Imports {
36 if imp.xml != nil {
37 protocol.Imports = append(protocol.Imports,
38 imp.xml.Translate(protocol))
39 }
40 }
41
42 for xmlName, srcName := range BaseTypeMap {
43 newBaseType := &Base{
44 srcName: srcName,
45 xmlName: xmlName,
46 size: newFixedSize(BaseTypeSizes[xmlName], true),
47 }
48 protocol.Types = append(protocol.Types, newBaseType)
49 }
50 for _, enum := range xml.Enums {
51 protocol.Types = append(protocol.Types, enum.Translate())
52 }
53 for _, xid := range xml.Xids {
54 protocol.Types = append(protocol.Types, xid.Translate())
55 }
56 for _, xidunion := range xml.XidUnions {
57 protocol.Types = append(protocol.Types, xidunion.Translate())
58 }
59 for _, typedef := range xml.TypeDefs {
60 protocol.Types = append(protocol.Types, typedef.Translate())
61 }
62 for _, s := range xml.Structs {
63 protocol.Types = append(protocol.Types, s.Translate())
64 }
65 for _, union := range xml.Unions {
66 protocol.Types = append(protocol.Types, union.Translate())
67 }
68 for _, ev := range xml.Events {
69 protocol.Types = append(protocol.Types, ev.Translate())
70 }
71 for _, evcopy := range xml.EventCopies {
72 protocol.Types = append(protocol.Types, evcopy.Translate())
73 }
74 for _, err := range xml.Errors {
75 protocol.Types = append(protocol.Types, err.Translate())
76 }
77 for _, errcopy := range xml.ErrorCopies {
78 protocol.Types = append(protocol.Types, errcopy.Translate())
79 }
80
81 for i, request := range xml.Requests {
82 protocol.Requests[i] = request.Translate()
83 }
84
85
86 protocol.Initialize()
87
88
89 for _, typ := range protocol.Types {
90 enum, ok := typ.(*Enum)
91 if !ok {
92 continue
93 }
94 nextValue := 0
95 for _, item := range enum.Items {
96 if item.Expr == nil {
97 item.Expr = &Value{v: nextValue}
98 nextValue++
99 } else {
100 nextValue = item.Expr.Eval() + 1
101 }
102 }
103 }
104
105 return protocol
106 }
107
108 func (x *XMLEnum) Translate() *Enum {
109 enum := &Enum{
110 xmlName: x.Name,
111 Items: make([]*EnumItem, len(x.Items)),
112 }
113 for i, item := range x.Items {
114 enum.Items[i] = &EnumItem{
115 xmlName: item.Name,
116 Expr: item.Expr.Translate(),
117 }
118 }
119 return enum
120 }
121
122 func (x *XMLXid) Translate() *Resource {
123 return &Resource{
124 xmlName: x.Name,
125 }
126 }
127
128 func (x *XMLTypeDef) Translate() *TypeDef {
129 return &TypeDef{
130 xmlName: x.New,
131 Old: newTranslation(x.Old),
132 }
133 }
134
135 func (x *XMLEvent) Translate() *Event {
136 ev := &Event{
137 xmlName: x.Name,
138 Number: x.Number,
139 NoSequence: x.NoSequence,
140 Fields: make([]Field, 0, len(x.Fields)),
141 }
142 for _, field := range x.Fields {
143 if field.XMLName.Local == "doc" {
144 continue
145 }
146 ev.Fields = append(ev.Fields, field.Translate(ev))
147 }
148 return ev
149 }
150
151 func (x *XMLEventCopy) Translate() *EventCopy {
152 return &EventCopy{
153 xmlName: x.Name,
154 Number: x.Number,
155 Old: newTranslation(x.Ref),
156 }
157 }
158
159 func (x *XMLError) Translate() *Error {
160 err := &Error{
161 xmlName: x.Name,
162 Number: x.Number,
163 Fields: make([]Field, len(x.Fields)),
164 }
165 for i, field := range x.Fields {
166 err.Fields[i] = field.Translate(err)
167 }
168 return err
169 }
170
171 func (x *XMLErrorCopy) Translate() *ErrorCopy {
172 return &ErrorCopy{
173 xmlName: x.Name,
174 Number: x.Number,
175 Old: newTranslation(x.Ref),
176 }
177 }
178
179 func (x *XMLStruct) Translate() *Struct {
180 s := &Struct{
181 xmlName: x.Name,
182 Fields: make([]Field, len(x.Fields)),
183 }
184 for i, field := range x.Fields {
185 s.Fields[i] = field.Translate(s)
186 }
187 return s
188 }
189
190 func (x *XMLUnion) Translate() *Union {
191 u := &Union{
192 xmlName: x.Name,
193 Fields: make([]Field, len(x.Fields)),
194 }
195 for i, field := range x.Fields {
196 u.Fields[i] = field.Translate(u)
197 }
198 return u
199 }
200
201 func (x *XMLRequest) Translate() *Request {
202 r := &Request{
203 xmlName: x.Name,
204 Opcode: x.Opcode,
205 Combine: x.Combine,
206 Fields: make([]Field, 0, len(x.Fields)),
207 Reply: x.Reply.Translate(),
208 }
209 for _, field := range x.Fields {
210 if field.XMLName.Local == "doc" || field.XMLName.Local == "fd" {
211 continue
212 }
213 r.Fields = append(r.Fields, field.Translate(r))
214 }
215
216
217
218
219
220
221 if x.Name == "QueryTextExtents" {
222 stringLenLocal := &LocalField{&SingleField{
223 xmlName: "string_len",
224 Type: newTranslation("CARD16"),
225 }}
226 r.Fields = append(r.Fields, stringLenLocal)
227 }
228
229 return r
230 }
231
232 func (x *XMLReply) Translate() *Reply {
233 if x == nil {
234 return nil
235 }
236
237 r := &Reply{
238 Fields: make([]Field, 0, len(x.Fields)),
239 }
240 for _, field := range x.Fields {
241 if field.XMLName.Local == "doc" || field.XMLName.Local == "fd" {
242 continue
243 }
244 r.Fields = append(r.Fields, field.Translate(r))
245 }
246 return r
247 }
248
249 func (x *XMLExpression) Translate() Expression {
250 if x == nil {
251 return nil
252 }
253
254 switch x.XMLName.Local {
255 case "op":
256 if len(x.Exprs) != 2 {
257 log.Panicf("'op' found %d expressions; expected 2.", len(x.Exprs))
258 }
259 return &BinaryOp{
260 Op: x.Op,
261 Expr1: x.Exprs[0].Translate(),
262 Expr2: x.Exprs[1].Translate(),
263 }
264 case "unop":
265 if len(x.Exprs) != 1 {
266 log.Panicf("'unop' found %d expressions; expected 1.", len(x.Exprs))
267 }
268 return &UnaryOp{
269 Op: x.Op,
270 Expr: x.Exprs[0].Translate(),
271 }
272 case "popcount":
273 if len(x.Exprs) != 1 {
274 log.Panicf("'popcount' found %d expressions; expected 1.",
275 len(x.Exprs))
276 }
277 return &PopCount{
278 Expr: x.Exprs[0].Translate(),
279 }
280 case "value":
281 val, err := strconv.Atoi(strings.TrimSpace(x.Data))
282 if err != nil {
283 log.Panicf("Could not convert '%s' in 'value' expression to int.",
284 x.Data)
285 }
286 return &Value{
287 v: val,
288 }
289 case "bit":
290 bit, err := strconv.Atoi(strings.TrimSpace(x.Data))
291 if err != nil {
292 log.Panicf("Could not convert '%s' in 'bit' expression to int.",
293 x.Data)
294 }
295 if bit < 0 || bit > 31 {
296 log.Panicf("A 'bit' literal must be in the range [0, 31], but "+
297 " is %d", bit)
298 }
299 return &Bit{
300 b: bit,
301 }
302 case "fieldref":
303 return &FieldRef{
304 Name: x.Data,
305 }
306 case "enumref":
307 return &EnumRef{
308 EnumKind: newTranslation(x.Ref),
309 EnumItem: x.Data,
310 }
311 case "sumof":
312 return &SumOf{
313 Name: x.Ref,
314 }
315 }
316
317 log.Panicf("Unrecognized tag '%s' in expression context. Expected one of "+
318 "op, fieldref, value, bit, enumref, unop, sumof or popcount.",
319 x.XMLName.Local)
320 panic("unreachable")
321 }
322
323 func (x *XMLField) Translate(parent interface{}) Field {
324 switch x.XMLName.Local {
325 case "pad":
326 return &PadField{
327 Bytes: x.Bytes,
328 }
329 case "field":
330 return &SingleField{
331 xmlName: x.Name,
332 Type: newTranslation(x.Type),
333 }
334 case "list":
335 return &ListField{
336 xmlName: x.Name,
337 Type: newTranslation(x.Type),
338 LengthExpr: x.Expr.Translate(),
339 }
340 case "localfield":
341 return &LocalField{&SingleField{
342 xmlName: x.Name,
343 Type: newTranslation(x.Type),
344 }}
345 case "exprfield":
346 return &ExprField{
347 xmlName: x.Name,
348 Type: newTranslation(x.Type),
349 Expr: x.Expr.Translate(),
350 }
351 case "valueparam":
352 return &ValueField{
353 Parent: parent,
354 MaskType: newTranslation(x.ValueMaskType),
355 MaskName: x.ValueMaskName,
356 ListName: x.ValueListName,
357 }
358 case "switch":
359 swtch := &SwitchField{
360 Name: x.Name,
361 Expr: x.Expr.Translate(),
362 Bitcases: make([]*Bitcase, len(x.Bitcases)),
363 }
364 for i, bitcase := range x.Bitcases {
365 swtch.Bitcases[i] = bitcase.Translate()
366 }
367 return swtch
368 }
369
370 log.Panicf("Unrecognized field element: %s", x.XMLName.Local)
371 panic("unreachable")
372 }
373
374 func (x *XMLBitcase) Translate() *Bitcase {
375 b := &Bitcase{
376 Expr: x.Expr().Translate(),
377 Fields: make([]Field, len(x.Fields)),
378 }
379 for i, field := range x.Fields {
380 b.Fields[i] = field.Translate(b)
381 }
382 return b
383 }
384
385
386
387 func SrcName(p *Protocol, name string) string {
388
389 if newn, ok := NameMap[name]; ok {
390 return newn
391 }
392 return splitAndTitle(name)
393 }
394
395 func TypeSrcName(p *Protocol, typ Type) string {
396 t := typ.XmlName()
397
398
399 if baseType, ok := typ.(*Base); ok {
400 return baseType.SrcName()
401 }
402
403
404 if newt, ok := TypeMap[t]; ok {
405 return newt
406 }
407
408
409 if colon := strings.Index(t, ":"); colon > -1 {
410 namespace := t[:colon]
411 rest := t[colon+1:]
412 return p.ProtocolFind(namespace).PkgName() + "." + splitAndTitle(rest)
413 }
414
415
416
417
418
419 if p.Parent == nil {
420 return splitAndTitle(t)
421 }
422 return p.PkgName() + "." + splitAndTitle(t)
423 }
424
View as plain text