1package internal
2
3import (
4	"unicode"
5	"unicode/utf8"
6)
7
8const (
9	// MaxTag is the maximum allowed tag number for a field.
10	MaxTag = 536870911 // 2^29 - 1
11
12	// SpecialReservedStart is the first tag in a range that is reserved and not
13	// allowed for use in message definitions.
14	SpecialReservedStart = 19000
15	// SpecialReservedEnd is the last tag in a range that is reserved and not
16	// allowed for use in message definitions.
17	SpecialReservedEnd = 19999
18
19	// NB: It would be nice to use constants from generated code instead of
20	// hard-coding these here. But code-gen does not emit these as constants
21	// anywhere. The only places they appear in generated code are struct tags
22	// on fields of the generated descriptor protos.
23
24	// File_packageTag is the tag number of the package element in a file
25	// descriptor proto.
26	File_packageTag = 2
27	// File_dependencyTag is the tag number of the dependencies element in a
28	// file descriptor proto.
29	File_dependencyTag = 3
30	// File_messagesTag is the tag number of the messages element in a file
31	// descriptor proto.
32	File_messagesTag = 4
33	// File_enumsTag is the tag number of the enums element in a file descriptor
34	// proto.
35	File_enumsTag = 5
36	// File_servicesTag is the tag number of the services element in a file
37	// descriptor proto.
38	File_servicesTag = 6
39	// File_extensionsTag is the tag number of the extensions element in a file
40	// descriptor proto.
41	File_extensionsTag = 7
42	// File_optionsTag is the tag number of the options element in a file
43	// descriptor proto.
44	File_optionsTag = 8
45	// File_syntaxTag is the tag number of the syntax element in a file
46	// descriptor proto.
47	File_syntaxTag = 12
48	// Message_nameTag is the tag number of the name element in a message
49	// descriptor proto.
50	Message_nameTag = 1
51	// Message_fieldsTag is the tag number of the fields element in a message
52	// descriptor proto.
53	Message_fieldsTag = 2
54	// Message_nestedMessagesTag is the tag number of the nested messages
55	// element in a message descriptor proto.
56	Message_nestedMessagesTag = 3
57	// Message_enumsTag is the tag number of the enums element in a message
58	// descriptor proto.
59	Message_enumsTag = 4
60	// Message_extensionRangeTag is the tag number of the extension ranges
61	// element in a message descriptor proto.
62	Message_extensionRangeTag = 5
63	// Message_extensionsTag is the tag number of the extensions element in a
64	// message descriptor proto.
65	Message_extensionsTag = 6
66	// Message_optionsTag is the tag number of the options element in a message
67	// descriptor proto.
68	Message_optionsTag = 7
69	// Message_oneOfsTag is the tag number of the one-ofs element in a message
70	// descriptor proto.
71	Message_oneOfsTag = 8
72	// Message_reservedRangeTag is the tag number of the reserved ranges element
73	// in a message descriptor proto.
74	Message_reservedRangeTag = 9
75	// Message_reservedNameTag is the tag number of the reserved names element
76	// in a message descriptor proto.
77	Message_reservedNameTag = 10
78	// ExtensionRange_startTag is the tag number of the start index in an
79	// extension range proto.
80	ExtensionRange_startTag = 1
81	// ExtensionRange_endTag is the tag number of the end index in an
82	// extension range proto.
83	ExtensionRange_endTag = 2
84	// ExtensionRange_optionsTag is the tag number of the options element in an
85	// extension range proto.
86	ExtensionRange_optionsTag = 3
87	// ReservedRange_startTag is the tag number of the start index in a reserved
88	// range proto.
89	ReservedRange_startTag = 1
90	// ReservedRange_endTag is the tag number of the end index in a reserved
91	// range proto.
92	ReservedRange_endTag = 2
93	// Field_nameTag is the tag number of the name element in a field descriptor
94	// proto.
95	Field_nameTag = 1
96	// Field_extendeeTag is the tag number of the extendee element in a field
97	// descriptor proto.
98	Field_extendeeTag = 2
99	// Field_numberTag is the tag number of the number element in a field
100	// descriptor proto.
101	Field_numberTag = 3
102	// Field_labelTag is the tag number of the label element in a field
103	// descriptor proto.
104	Field_labelTag = 4
105	// Field_typeTag is the tag number of the type element in a field descriptor
106	// proto.
107	Field_typeTag = 5
108	// Field_typeNameTag is the tag number of the type name element in a field
109	// descriptor proto.
110	Field_typeNameTag = 6
111	// Field_defaultTag is the tag number of the default value element in a
112	// field descriptor proto.
113	Field_defaultTag = 7
114	// Field_optionsTag is the tag number of the options element in a field
115	// descriptor proto.
116	Field_optionsTag = 8
117	// Field_jsonNameTag is the tag number of the JSON name element in a field
118	// descriptor proto.
119	Field_jsonNameTag = 10
120	// OneOf_nameTag is the tag number of the name element in a one-of
121	// descriptor proto.
122	OneOf_nameTag = 1
123	// OneOf_optionsTag is the tag number of the options element in a one-of
124	// descriptor proto.
125	OneOf_optionsTag = 2
126	// Enum_nameTag is the tag number of the name element in an enum descriptor
127	// proto.
128	Enum_nameTag = 1
129	// Enum_valuesTag is the tag number of the values element in an enum
130	// descriptor proto.
131	Enum_valuesTag = 2
132	// Enum_optionsTag is the tag number of the options element in an enum
133	// descriptor proto.
134	Enum_optionsTag = 3
135	// Enum_reservedRangeTag is the tag number of the reserved ranges element in
136	// an enum descriptor proto.
137	Enum_reservedRangeTag = 4
138	// Enum_reservedNameTag is the tag number of the reserved names element in
139	// an enum descriptor proto.
140	Enum_reservedNameTag = 5
141	// EnumVal_nameTag is the tag number of the name element in an enum value
142	// descriptor proto.
143	EnumVal_nameTag = 1
144	// EnumVal_numberTag is the tag number of the number element in an enum
145	// value descriptor proto.
146	EnumVal_numberTag = 2
147	// EnumVal_optionsTag is the tag number of the options element in an enum
148	// value descriptor proto.
149	EnumVal_optionsTag = 3
150	// Service_nameTag is the tag number of the name element in a service
151	// descriptor proto.
152	Service_nameTag = 1
153	// Service_methodsTag is the tag number of the methods element in a service
154	// descriptor proto.
155	Service_methodsTag = 2
156	// Service_optionsTag is the tag number of the options element in a service
157	// descriptor proto.
158	Service_optionsTag = 3
159	// Method_nameTag is the tag number of the name element in a method
160	// descriptor proto.
161	Method_nameTag = 1
162	// Method_inputTag is the tag number of the input type element in a method
163	// descriptor proto.
164	Method_inputTag = 2
165	// Method_outputTag is the tag number of the output type element in a method
166	// descriptor proto.
167	Method_outputTag = 3
168	// Method_optionsTag is the tag number of the options element in a method
169	// descriptor proto.
170	Method_optionsTag = 4
171	// Method_inputStreamTag is the tag number of the input stream flag in a
172	// method descriptor proto.
173	Method_inputStreamTag = 5
174	// Method_outputStreamTag is the tag number of the output stream flag in a
175	// method descriptor proto.
176	Method_outputStreamTag = 6
177
178	// UninterpretedOptionsTag is the tag number of the uninterpreted options
179	// element. All *Options messages use the same tag for the field that stores
180	// uninterpreted options.
181	UninterpretedOptionsTag = 999
182
183	// Uninterpreted_nameTag is the tag number of the name element in an
184	// uninterpreted options proto.
185	Uninterpreted_nameTag = 2
186	// Uninterpreted_identTag is the tag number of the identifier value in an
187	// uninterpreted options proto.
188	Uninterpreted_identTag = 3
189	// Uninterpreted_posIntTag is the tag number of the positive int value in an
190	// uninterpreted options proto.
191	Uninterpreted_posIntTag = 4
192	// Uninterpreted_negIntTag is the tag number of the negative int value in an
193	// uninterpreted options proto.
194	Uninterpreted_negIntTag = 5
195	// Uninterpreted_doubleTag is the tag number of the double value in an
196	// uninterpreted options proto.
197	Uninterpreted_doubleTag = 6
198	// Uninterpreted_stringTag is the tag number of the string value in an
199	// uninterpreted options proto.
200	Uninterpreted_stringTag = 7
201	// Uninterpreted_aggregateTag is the tag number of the aggregate value in an
202	// uninterpreted options proto.
203	Uninterpreted_aggregateTag = 8
204	// UninterpretedName_nameTag is the tag number of the name element in an
205	// uninterpreted option name proto.
206	UninterpretedName_nameTag = 1
207)
208
209// JsonName returns the default JSON name for a field with the given name.
210func JsonName(name string) string {
211	var js []rune
212	nextUpper := false
213	for i, r := range name {
214		if r == '_' {
215			nextUpper = true
216			continue
217		}
218		if i == 0 {
219			js = append(js, r)
220		} else if nextUpper {
221			nextUpper = false
222			js = append(js, unicode.ToUpper(r))
223		} else {
224			js = append(js, r)
225		}
226	}
227	return string(js)
228}
229
230// InitCap returns the given field name, but with the first letter capitalized.
231func InitCap(name string) string {
232	r, sz := utf8.DecodeRuneInString(name)
233	return string(unicode.ToUpper(r)) + name[sz:]
234}
235
236// CreatePrefixList returns a list of package prefixes to search when resolving
237// a symbol name. If the given package is blank, it returns only the empty
238// string. If the given package contains only one token, e.g. "foo", it returns
239// that token and the empty string, e.g. ["foo", ""]. Otherwise, it returns
240// successively shorter prefixes of the package and then the empty string. For
241// example, for a package named "foo.bar.baz" it will return the following list:
242//   ["foo.bar.baz", "foo.bar", "foo", ""]
243func CreatePrefixList(pkg string) []string {
244	if pkg == "" {
245		return []string{""}
246	}
247
248	numDots := 0
249	// one pass to pre-allocate the returned slice
250	for i := 0; i < len(pkg); i++ {
251		if pkg[i] == '.' {
252			numDots++
253		}
254	}
255	if numDots == 0 {
256		return []string{pkg, ""}
257	}
258
259	prefixes := make([]string, numDots+2)
260	// second pass to fill in returned slice
261	for i := 0; i < len(pkg); i++ {
262		if pkg[i] == '.' {
263			prefixes[numDots] = pkg[:i]
264			numDots--
265		}
266	}
267	prefixes[0] = pkg
268
269	return prefixes
270}
271