1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
package php
import (
"bytes"
"fmt"
"strings"
desc "google.golang.org/protobuf/types/descriptorpb"
plugin "google.golang.org/protobuf/types/pluginpb"
)
// manages internal name representation of the package
type ns struct {
// Package defines file package.
Package string
// Root namespace of the package
Namespace string
// Import declares what namespaces to be imported
Import map[string]string
}
// newNamespace creates new work namespace.
func newNamespace(req *plugin.CodeGeneratorRequest, file *desc.FileDescriptorProto, service *desc.ServiceDescriptorProto) *ns {
ns := &ns{
Package: *file.Package,
Namespace: namespace(file.Package, "\\"),
Import: make(map[string]string),
}
if file.Options != nil && file.Options.PhpNamespace != nil {
ns.Namespace = *file.Options.PhpNamespace
}
for k := range service.Method {
ns.importMessage(req, service.Method[k].InputType)
ns.importMessage(req, service.Method[k].OutputType)
}
return ns
}
// importMessage registers new import message namespace (only the namespace).
func (ns *ns) importMessage(req *plugin.CodeGeneratorRequest, msg *string) {
if msg == nil {
return
}
chunks := strings.Split(*msg, ".")
pkg := strings.Join(chunks[:len(chunks)-1], ".")
result := bytes.NewBuffer(nil)
for _, p := range chunks[:len(chunks)-1] {
result.WriteString(identifier(p, ""))
result.WriteString(`\`)
}
if pkg == "."+ns.Package {
// root package
return
}
for _, f := range req.ProtoFile {
if pkg == "."+*f.Package {
if f.Options != nil && f.Options.PhpNamespace != nil {
// custom imported namespace
ns.Import[pkg] = *f.Options.PhpNamespace
return
}
}
}
ns.Import[pkg] = strings.Trim(result.String(), `\`)
}
// resolve message alias
func (ns *ns) resolve(msg *string) string {
chunks := strings.Split(*msg, ".")
pkg := strings.Join(chunks[:len(chunks)-1], ".")
if pkg == "."+ns.Package {
// root message
return identifier(chunks[len(chunks)-1], "")
}
for iPkg, ns := range ns.Import {
if pkg == iPkg {
// use last namespace chunk
nsChunks := strings.Split(ns, `\`)
identifier := identifier(chunks[len(chunks)-1], "")
return fmt.Sprintf(
`%s\%s`,
nsChunks[len(nsChunks)-1],
resolveReserved(identifier, pkg),
)
}
}
// fully clarified name (fallback)
return "\\" + namespace(msg, "\\")
}
|