diff options
25 files changed, 1 insertions, 6287 deletions
@@ -13,17 +13,7 @@ | |||
13 | # See the License for the specific language governing permissions and | 13 | # See the License for the specific language governing permissions and |
14 | # limitations under the License. | 14 | # limitations under the License. |
15 | 15 | ||
16 | GERRIT_SRC=../gerrit | ||
17 | GERRIT_MODULES=codereview froofle | ||
18 | |||
19 | all: | 16 | all: |
20 | 17 | ||
21 | clean: | 18 | clean: |
22 | find . -name \*.pyc -type f | xargs rm -f | 19 | find . -name \*.pyc -type f | xargs rm -f |
23 | |||
24 | update-pyclient: | ||
25 | $(MAKE) -C $(GERRIT_SRC) release-pyclient | ||
26 | rm -rf $(GERRIT_MODULES) | ||
27 | (cd $(GERRIT_SRC)/release/pyclient && \ | ||
28 | find . -type f \ | ||
29 | | cpio -pd $(abspath .)) | ||
diff --git a/codereview/__init__.py b/codereview/__init__.py deleted file mode 100644 index 58835553..00000000 --- a/codereview/__init__.py +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | __version__ = 'v1.0-112-gbcd4db5a' | ||
diff --git a/codereview/need_retry_pb2.py b/codereview/need_retry_pb2.py deleted file mode 100644 index 3fab2d43..00000000 --- a/codereview/need_retry_pb2.py +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | #!/usr/bin/python2.4 | ||
2 | # Generated by the protocol buffer compiler. DO NOT EDIT! | ||
3 | |||
4 | from froofle.protobuf import descriptor | ||
5 | from froofle.protobuf import message | ||
6 | from froofle.protobuf import reflection | ||
7 | from froofle.protobuf import service | ||
8 | from froofle.protobuf import service_reflection | ||
9 | from froofle.protobuf import descriptor_pb2 | ||
10 | |||
11 | |||
12 | |||
13 | _RETRYREQUESTLATERRESPONSE = descriptor.Descriptor( | ||
14 | name='RetryRequestLaterResponse', | ||
15 | full_name='codereview.RetryRequestLaterResponse', | ||
16 | filename='need_retry.proto', | ||
17 | containing_type=None, | ||
18 | fields=[ | ||
19 | ], | ||
20 | extensions=[ | ||
21 | ], | ||
22 | nested_types=[], # TODO(robinson): Implement. | ||
23 | enum_types=[ | ||
24 | ], | ||
25 | options=None) | ||
26 | |||
27 | |||
28 | |||
29 | class RetryRequestLaterResponse(message.Message): | ||
30 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
31 | DESCRIPTOR = _RETRYREQUESTLATERRESPONSE | ||
32 | |||
diff --git a/codereview/proto_client.py b/codereview/proto_client.py deleted file mode 100755 index b58cf6a8..00000000 --- a/codereview/proto_client.py +++ /dev/null | |||
@@ -1,380 +0,0 @@ | |||
1 | # Copyright 2007, 2008 Google Inc. | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | import base64 | ||
16 | import cookielib | ||
17 | import getpass | ||
18 | import logging | ||
19 | import md5 | ||
20 | import os | ||
21 | import random | ||
22 | import socket | ||
23 | import sys | ||
24 | import time | ||
25 | import urllib | ||
26 | import urllib2 | ||
27 | import urlparse | ||
28 | |||
29 | from froofle.protobuf.service import RpcChannel | ||
30 | from froofle.protobuf.service import RpcController | ||
31 | from need_retry_pb2 import RetryRequestLaterResponse; | ||
32 | |||
33 | _cookie_jars = {} | ||
34 | |||
35 | def _open_jar(path): | ||
36 | auth = False | ||
37 | |||
38 | if path is None: | ||
39 | c = cookielib.CookieJar() | ||
40 | else: | ||
41 | c = _cookie_jars.get(path) | ||
42 | if c is None: | ||
43 | c = cookielib.MozillaCookieJar(path) | ||
44 | |||
45 | if os.path.exists(path): | ||
46 | try: | ||
47 | c.load() | ||
48 | auth = True | ||
49 | except (cookielib.LoadError, IOError): | ||
50 | pass | ||
51 | |||
52 | if auth: | ||
53 | print >>sys.stderr, \ | ||
54 | 'Loaded authentication cookies from %s' \ | ||
55 | % path | ||
56 | else: | ||
57 | os.close(os.open(path, os.O_CREAT, 0600)) | ||
58 | os.chmod(path, 0600) | ||
59 | _cookie_jars[path] = c | ||
60 | else: | ||
61 | auth = True | ||
62 | return c, auth | ||
63 | |||
64 | |||
65 | class ClientLoginError(urllib2.HTTPError): | ||
66 | """Raised to indicate an error authenticating with ClientLogin.""" | ||
67 | |||
68 | def __init__(self, url, code, msg, headers, args): | ||
69 | urllib2.HTTPError.__init__(self, url, code, msg, headers, None) | ||
70 | self.args = args | ||
71 | self.reason = args["Error"] | ||
72 | |||
73 | |||
74 | class Proxy(object): | ||
75 | class _ResultHolder(object): | ||
76 | def __call__(self, result): | ||
77 | self._result = result | ||
78 | |||
79 | class _RemoteController(RpcController): | ||
80 | def Reset(self): | ||
81 | pass | ||
82 | |||
83 | def Failed(self): | ||
84 | pass | ||
85 | |||
86 | def ErrorText(self): | ||
87 | pass | ||
88 | |||
89 | def StartCancel(self): | ||
90 | pass | ||
91 | |||
92 | def SetFailed(self, reason): | ||
93 | raise RuntimeError, reason | ||
94 | |||
95 | def IsCancelled(self): | ||
96 | pass | ||
97 | |||
98 | def NotifyOnCancel(self, callback): | ||
99 | pass | ||
100 | |||
101 | def __init__(self, stub): | ||
102 | self._stub = stub | ||
103 | |||
104 | def __getattr__(self, key): | ||
105 | method = getattr(self._stub, key) | ||
106 | |||
107 | def call(request): | ||
108 | done = self._ResultHolder() | ||
109 | method(self._RemoteController(), request, done) | ||
110 | return done._result | ||
111 | |||
112 | return call | ||
113 | |||
114 | |||
115 | class HttpRpc(RpcChannel): | ||
116 | """Simple protobuf over HTTP POST implementation.""" | ||
117 | |||
118 | def __init__(self, host, auth_function, | ||
119 | host_override=None, | ||
120 | extra_headers={}, | ||
121 | cookie_file=None): | ||
122 | """Creates a new HttpRpc. | ||
123 | |||
124 | Args: | ||
125 | host: The host to send requests to. | ||
126 | auth_function: A function that takes no arguments and returns an | ||
127 | (email, password) tuple when called. Will be called if authentication | ||
128 | is required. | ||
129 | host_override: The host header to send to the server (defaults to host). | ||
130 | extra_headers: A dict of extra headers to append to every request. | ||
131 | cookie_file: If not None, name of the file in ~/ to save the | ||
132 | cookie jar into. Applications are encouraged to set this to | ||
133 | '.$appname_cookies' or some otherwise unique name. | ||
134 | """ | ||
135 | self.host = host.lower() | ||
136 | self.host_override = host_override | ||
137 | self.auth_function = auth_function | ||
138 | self.authenticated = False | ||
139 | self.extra_headers = extra_headers | ||
140 | self.xsrf_token = None | ||
141 | if cookie_file is None: | ||
142 | self.cookie_file = None | ||
143 | else: | ||
144 | self.cookie_file = os.path.expanduser("~/%s" % cookie_file) | ||
145 | self.opener = self._GetOpener() | ||
146 | if self.host_override: | ||
147 | logging.info("Server: %s; Host: %s", self.host, self.host_override) | ||
148 | else: | ||
149 | logging.info("Server: %s", self.host) | ||
150 | |||
151 | def CallMethod(self, method, controller, request, response_type, done): | ||
152 | pat = "application/x-google-protobuf; name=%s" | ||
153 | |||
154 | url = "/proto/%s/%s" % (method.containing_service.name, method.name) | ||
155 | reqbin = request.SerializeToString() | ||
156 | reqtyp = pat % request.DESCRIPTOR.full_name | ||
157 | reqmd5 = base64.b64encode(md5.new(reqbin).digest()) | ||
158 | |||
159 | start = time.time() | ||
160 | while True: | ||
161 | t, b = self._Send(url, reqbin, reqtyp, reqmd5) | ||
162 | if t == (pat % RetryRequestLaterResponse.DESCRIPTOR.full_name): | ||
163 | if time.time() >= (start + 1800): | ||
164 | controller.SetFailed("timeout") | ||
165 | return | ||
166 | s = random.uniform(0.250, 2.000) | ||
167 | print "Busy, retrying in %.3f seconds ..." % s | ||
168 | time.sleep(s) | ||
169 | continue | ||
170 | |||
171 | if t == (pat % response_type.DESCRIPTOR.full_name): | ||
172 | response = response_type() | ||
173 | response.ParseFromString(b) | ||
174 | done(response) | ||
175 | else: | ||
176 | controller.SetFailed("Unexpected %s response" % t) | ||
177 | break | ||
178 | |||
179 | def _CreateRequest(self, url, data=None): | ||
180 | """Creates a new urllib request.""" | ||
181 | logging.debug("Creating request for: '%s' with payload:\n%s", url, data) | ||
182 | req = urllib2.Request(url, data=data) | ||
183 | if self.host_override: | ||
184 | req.add_header("Host", self.host_override) | ||
185 | for key, value in self.extra_headers.iteritems(): | ||
186 | req.add_header(key, value) | ||
187 | return req | ||
188 | |||
189 | def _GetAuthToken(self, email, password): | ||
190 | """Uses ClientLogin to authenticate the user, returning an auth token. | ||
191 | |||
192 | Args: | ||
193 | email: The user's email address | ||
194 | password: The user's password | ||
195 | |||
196 | Raises: | ||
197 | ClientLoginError: If there was an error authenticating with ClientLogin. | ||
198 | HTTPError: If there was some other form of HTTP error. | ||
199 | |||
200 | Returns: | ||
201 | The authentication token returned by ClientLogin. | ||
202 | """ | ||
203 | account_type = 'GOOGLE' | ||
204 | if self.host.endswith('.google.com'): | ||
205 | account_type = 'HOSTED' | ||
206 | |||
207 | req = self._CreateRequest( | ||
208 | url="https://www.google.com/accounts/ClientLogin", | ||
209 | data=urllib.urlencode({ | ||
210 | "Email": email, | ||
211 | "Passwd": password, | ||
212 | "service": "ah", | ||
213 | "source": "gerrit-codereview-client", | ||
214 | "accountType": account_type, | ||
215 | }) | ||
216 | ) | ||
217 | try: | ||
218 | response = self.opener.open(req) | ||
219 | response_body = response.read() | ||
220 | response_dict = dict(x.split("=") | ||
221 | for x in response_body.split("\n") if x) | ||
222 | return response_dict["Auth"] | ||
223 | except urllib2.HTTPError, e: | ||
224 | if e.code == 403: | ||
225 | body = e.read() | ||
226 | response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) | ||
227 | raise ClientLoginError(req.get_full_url(), e.code, e.msg, | ||
228 | e.headers, response_dict) | ||
229 | else: | ||
230 | raise | ||
231 | |||
232 | def _GetAuthCookie(self, auth_token): | ||
233 | """Fetches authentication cookies for an authentication token. | ||
234 | |||
235 | Args: | ||
236 | auth_token: The authentication token returned by ClientLogin. | ||
237 | |||
238 | Raises: | ||
239 | HTTPError: If there was an error fetching the authentication cookies. | ||
240 | """ | ||
241 | # This is a dummy value to allow us to identify when we're successful. | ||
242 | continue_location = "http://localhost/" | ||
243 | args = {"continue": continue_location, "auth": auth_token} | ||
244 | req = self._CreateRequest("http://%s/_ah/login?%s" % | ||
245 | (self.host, urllib.urlencode(args))) | ||
246 | try: | ||
247 | response = self.opener.open(req) | ||
248 | except urllib2.HTTPError, e: | ||
249 | response = e | ||
250 | if (response.code != 302 or | ||
251 | response.info()["location"] != continue_location): | ||
252 | raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, | ||
253 | response.headers, response.fp) | ||
254 | |||
255 | def _GetXsrfToken(self): | ||
256 | """Fetches /proto/_token for use in X-XSRF-Token HTTP header. | ||
257 | |||
258 | Raises: | ||
259 | HTTPError: If there was an error fetching a new token. | ||
260 | """ | ||
261 | tries = 0 | ||
262 | while True: | ||
263 | url = "http://%s/proto/_token" % self.host | ||
264 | req = self._CreateRequest(url) | ||
265 | try: | ||
266 | response = self.opener.open(req) | ||
267 | self.xsrf_token = response.read() | ||
268 | return | ||
269 | except urllib2.HTTPError, e: | ||
270 | if tries > 3: | ||
271 | raise | ||
272 | elif e.code == 401: | ||
273 | self._Authenticate() | ||
274 | else: | ||
275 | raise | ||
276 | |||
277 | def _Authenticate(self): | ||
278 | """Authenticates the user. | ||
279 | |||
280 | The authentication process works as follows: | ||
281 | 1) We get a username and password from the user | ||
282 | 2) We use ClientLogin to obtain an AUTH token for the user | ||
283 | (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). | ||
284 | 3) We pass the auth token to /_ah/login on the server to obtain an | ||
285 | authentication cookie. If login was successful, it tries to redirect | ||
286 | us to the URL we provided. | ||
287 | |||
288 | If we attempt to access the upload API without first obtaining an | ||
289 | authentication cookie, it returns a 401 response and directs us to | ||
290 | authenticate ourselves with ClientLogin. | ||
291 | """ | ||
292 | attempts = 0 | ||
293 | while True: | ||
294 | attempts += 1 | ||
295 | try: | ||
296 | cred = self.auth_function() | ||
297 | auth_token = self._GetAuthToken(cred[0], cred[1]) | ||
298 | except ClientLoginError: | ||
299 | if attempts < 3: | ||
300 | continue | ||
301 | raise | ||
302 | self._GetAuthCookie(auth_token) | ||
303 | self.authenticated = True | ||
304 | if self.cookie_file is not None: | ||
305 | print >>sys.stderr, \ | ||
306 | 'Saving authentication cookies to %s' \ | ||
307 | % self.cookie_file | ||
308 | self.cookie_jar.save() | ||
309 | return | ||
310 | |||
311 | def _Send(self, request_path, payload, content_type, content_md5): | ||
312 | """Sends an RPC and returns the response. | ||
313 | |||
314 | Args: | ||
315 | request_path: The path to send the request to, eg /api/appversion/create. | ||
316 | payload: The body of the request, or None to send an empty request. | ||
317 | content_type: The Content-Type header to use. | ||
318 | content_md5: The Content-MD5 header to use. | ||
319 | |||
320 | Returns: | ||
321 | The content type, as a string. | ||
322 | The response body, as a string. | ||
323 | """ | ||
324 | if not self.authenticated: | ||
325 | self._Authenticate() | ||
326 | if not self.xsrf_token: | ||
327 | self._GetXsrfToken() | ||
328 | |||
329 | old_timeout = socket.getdefaulttimeout() | ||
330 | socket.setdefaulttimeout(None) | ||
331 | try: | ||
332 | tries = 0 | ||
333 | while True: | ||
334 | tries += 1 | ||
335 | url = "http://%s%s" % (self.host, request_path) | ||
336 | req = self._CreateRequest(url=url, data=payload) | ||
337 | req.add_header("Content-Type", content_type) | ||
338 | req.add_header("Content-MD5", content_md5) | ||
339 | req.add_header("X-XSRF-Token", self.xsrf_token) | ||
340 | try: | ||
341 | f = self.opener.open(req) | ||
342 | hdr = f.info() | ||
343 | type = hdr.getheader('Content-Type', | ||
344 | 'application/octet-stream') | ||
345 | response = f.read() | ||
346 | f.close() | ||
347 | return type, response | ||
348 | except urllib2.HTTPError, e: | ||
349 | if tries > 3: | ||
350 | raise | ||
351 | elif e.code == 401: | ||
352 | self._Authenticate() | ||
353 | elif e.code == 403: | ||
354 | if not hasattr(e, 'read'): | ||
355 | e.read = lambda self: '' | ||
356 | raise RuntimeError, '403\nxsrf: %s\n%s' \ | ||
357 | % (self.xsrf_token, e.read()) | ||
358 | else: | ||
359 | raise | ||
360 | finally: | ||
361 | socket.setdefaulttimeout(old_timeout) | ||
362 | |||
363 | def _GetOpener(self): | ||
364 | """Returns an OpenerDirector that supports cookies and ignores redirects. | ||
365 | |||
366 | Returns: | ||
367 | A urllib2.OpenerDirector object. | ||
368 | """ | ||
369 | opener = urllib2.OpenerDirector() | ||
370 | opener.add_handler(urllib2.ProxyHandler()) | ||
371 | opener.add_handler(urllib2.UnknownHandler()) | ||
372 | opener.add_handler(urllib2.HTTPHandler()) | ||
373 | opener.add_handler(urllib2.HTTPDefaultErrorHandler()) | ||
374 | opener.add_handler(urllib2.HTTPSHandler()) | ||
375 | opener.add_handler(urllib2.HTTPErrorProcessor()) | ||
376 | |||
377 | self.cookie_jar, \ | ||
378 | self.authenticated = _open_jar(self.cookie_file) | ||
379 | opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) | ||
380 | return opener | ||
diff --git a/codereview/review_pb2.py b/codereview/review_pb2.py deleted file mode 100644 index 0896feba..00000000 --- a/codereview/review_pb2.py +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | #!/usr/bin/python2.4 | ||
2 | # Generated by the protocol buffer compiler. DO NOT EDIT! | ||
3 | |||
4 | from froofle.protobuf import descriptor | ||
5 | from froofle.protobuf import message | ||
6 | from froofle.protobuf import reflection | ||
7 | from froofle.protobuf import service | ||
8 | from froofle.protobuf import service_reflection | ||
9 | from froofle.protobuf import descriptor_pb2 | ||
10 | |||
11 | |||
12 | import upload_bundle_pb2 | ||
13 | |||
14 | |||
15 | |||
16 | _REVIEWSERVICE = descriptor.ServiceDescriptor( | ||
17 | name='ReviewService', | ||
18 | full_name='codereview.ReviewService', | ||
19 | index=0, | ||
20 | options=None, | ||
21 | methods=[ | ||
22 | descriptor.MethodDescriptor( | ||
23 | name='UploadBundle', | ||
24 | full_name='codereview.ReviewService.UploadBundle', | ||
25 | index=0, | ||
26 | containing_service=None, | ||
27 | input_type=upload_bundle_pb2._UPLOADBUNDLEREQUEST, | ||
28 | output_type=upload_bundle_pb2._UPLOADBUNDLERESPONSE, | ||
29 | options=None, | ||
30 | ), | ||
31 | descriptor.MethodDescriptor( | ||
32 | name='ContinueBundle', | ||
33 | full_name='codereview.ReviewService.ContinueBundle', | ||
34 | index=1, | ||
35 | containing_service=None, | ||
36 | input_type=upload_bundle_pb2._UPLOADBUNDLECONTINUE, | ||
37 | output_type=upload_bundle_pb2._UPLOADBUNDLERESPONSE, | ||
38 | options=None, | ||
39 | ), | ||
40 | ]) | ||
41 | |||
42 | class ReviewService(service.Service): | ||
43 | __metaclass__ = service_reflection.GeneratedServiceType | ||
44 | DESCRIPTOR = _REVIEWSERVICE | ||
45 | class ReviewService_Stub(ReviewService): | ||
46 | __metaclass__ = service_reflection.GeneratedServiceStubType | ||
47 | DESCRIPTOR = _REVIEWSERVICE | ||
48 | |||
diff --git a/codereview/upload_bundle_pb2.py b/codereview/upload_bundle_pb2.py deleted file mode 100644 index ff91ee1f..00000000 --- a/codereview/upload_bundle_pb2.py +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
1 | #!/usr/bin/python2.4 | ||
2 | # Generated by the protocol buffer compiler. DO NOT EDIT! | ||
3 | |||
4 | from froofle.protobuf import descriptor | ||
5 | from froofle.protobuf import message | ||
6 | from froofle.protobuf import reflection | ||
7 | from froofle.protobuf import service | ||
8 | from froofle.protobuf import service_reflection | ||
9 | from froofle.protobuf import descriptor_pb2 | ||
10 | |||
11 | |||
12 | _UPLOADBUNDLERESPONSE_CODETYPE = descriptor.EnumDescriptor( | ||
13 | name='CodeType', | ||
14 | full_name='codereview.UploadBundleResponse.CodeType', | ||
15 | filename='CodeType', | ||
16 | values=[ | ||
17 | descriptor.EnumValueDescriptor( | ||
18 | name='RECEIVED', index=0, number=1, | ||
19 | options=None, | ||
20 | type=None), | ||
21 | descriptor.EnumValueDescriptor( | ||
22 | name='CONTINUE', index=1, number=4, | ||
23 | options=None, | ||
24 | type=None), | ||
25 | descriptor.EnumValueDescriptor( | ||
26 | name='UNAUTHORIZED_USER', index=2, number=7, | ||
27 | options=None, | ||
28 | type=None), | ||
29 | descriptor.EnumValueDescriptor( | ||
30 | name='UNKNOWN_CHANGE', index=3, number=9, | ||
31 | options=None, | ||
32 | type=None), | ||
33 | descriptor.EnumValueDescriptor( | ||
34 | name='CHANGE_CLOSED', index=4, number=10, | ||
35 | options=None, | ||
36 | type=None), | ||
37 | descriptor.EnumValueDescriptor( | ||
38 | name='UNKNOWN_EMAIL', index=5, number=11, | ||
39 | options=None, | ||
40 | type=None), | ||
41 | descriptor.EnumValueDescriptor( | ||
42 | name='UNKNOWN_PROJECT', index=6, number=2, | ||
43 | options=None, | ||
44 | type=None), | ||
45 | descriptor.EnumValueDescriptor( | ||
46 | name='UNKNOWN_BRANCH', index=7, number=3, | ||
47 | options=None, | ||
48 | type=None), | ||
49 | descriptor.EnumValueDescriptor( | ||
50 | name='UNKNOWN_BUNDLE', index=8, number=5, | ||
51 | options=None, | ||
52 | type=None), | ||
53 | descriptor.EnumValueDescriptor( | ||
54 | name='NOT_BUNDLE_OWNER', index=9, number=6, | ||
55 | options=None, | ||
56 | type=None), | ||
57 | descriptor.EnumValueDescriptor( | ||
58 | name='BUNDLE_CLOSED', index=10, number=8, | ||
59 | options=None, | ||
60 | type=None), | ||
61 | ], | ||
62 | options=None, | ||
63 | ) | ||
64 | |||
65 | |||
66 | _REPLACEPATCHSET = descriptor.Descriptor( | ||
67 | name='ReplacePatchSet', | ||
68 | full_name='codereview.ReplacePatchSet', | ||
69 | filename='upload_bundle.proto', | ||
70 | containing_type=None, | ||
71 | fields=[ | ||
72 | descriptor.FieldDescriptor( | ||
73 | name='change_id', full_name='codereview.ReplacePatchSet.change_id', index=0, | ||
74 | number=1, type=9, cpp_type=9, label=2, | ||
75 | default_value=unicode("", "utf-8"), | ||
76 | message_type=None, enum_type=None, containing_type=None, | ||
77 | is_extension=False, extension_scope=None, | ||
78 | options=None), | ||
79 | descriptor.FieldDescriptor( | ||
80 | name='object_id', full_name='codereview.ReplacePatchSet.object_id', index=1, | ||
81 | number=2, type=9, cpp_type=9, label=2, | ||
82 | default_value=unicode("", "utf-8"), | ||
83 | message_type=None, enum_type=None, containing_type=None, | ||
84 | is_extension=False, extension_scope=None, | ||
85 | options=None), | ||
86 | ], | ||
87 | extensions=[ | ||
88 | ], | ||
89 | nested_types=[], # TODO(robinson): Implement. | ||
90 | enum_types=[ | ||
91 | ], | ||
92 | options=None) | ||
93 | |||
94 | |||
95 | _UPLOADBUNDLEREQUEST = descriptor.Descriptor( | ||
96 | name='UploadBundleRequest', | ||
97 | full_name='codereview.UploadBundleRequest', | ||
98 | filename='upload_bundle.proto', | ||
99 | containing_type=None, | ||
100 | fields=[ | ||
101 | descriptor.FieldDescriptor( | ||
102 | name='dest_project', full_name='codereview.UploadBundleRequest.dest_project', index=0, | ||
103 | number=10, type=9, cpp_type=9, label=2, | ||
104 | default_value=unicode("", "utf-8"), | ||
105 | message_type=None, enum_type=None, containing_type=None, | ||
106 | is_extension=False, extension_scope=None, | ||
107 | options=None), | ||
108 | descriptor.FieldDescriptor( | ||
109 | name='dest_branch', full_name='codereview.UploadBundleRequest.dest_branch', index=1, | ||
110 | number=11, type=9, cpp_type=9, label=2, | ||
111 | default_value=unicode("", "utf-8"), | ||
112 | message_type=None, enum_type=None, containing_type=None, | ||
113 | is_extension=False, extension_scope=None, | ||
114 | options=None), | ||
115 | descriptor.FieldDescriptor( | ||
116 | name='partial_upload', full_name='codereview.UploadBundleRequest.partial_upload', index=2, | ||
117 | number=12, type=8, cpp_type=7, label=2, | ||
118 | default_value=False, | ||
119 | message_type=None, enum_type=None, containing_type=None, | ||
120 | is_extension=False, extension_scope=None, | ||
121 | options=None), | ||
122 | descriptor.FieldDescriptor( | ||
123 | name='bundle_data', full_name='codereview.UploadBundleRequest.bundle_data', index=3, | ||
124 | number=13, type=12, cpp_type=9, label=2, | ||
125 | default_value="", | ||
126 | message_type=None, enum_type=None, containing_type=None, | ||
127 | is_extension=False, extension_scope=None, | ||
128 | options=None), | ||
129 | descriptor.FieldDescriptor( | ||
130 | name='contained_object', full_name='codereview.UploadBundleRequest.contained_object', index=4, | ||
131 | number=1, type=9, cpp_type=9, label=3, | ||
132 | default_value=[], | ||
133 | message_type=None, enum_type=None, containing_type=None, | ||
134 | is_extension=False, extension_scope=None, | ||
135 | options=None), | ||
136 | descriptor.FieldDescriptor( | ||
137 | name='replace', full_name='codereview.UploadBundleRequest.replace', index=5, | ||
138 | number=2, type=11, cpp_type=10, label=3, | ||
139 | default_value=[], | ||
140 | message_type=None, enum_type=None, containing_type=None, | ||
141 | is_extension=False, extension_scope=None, | ||
142 | options=None), | ||
143 | descriptor.FieldDescriptor( | ||
144 | name='reviewers', full_name='codereview.UploadBundleRequest.reviewers', index=6, | ||
145 | number=3, type=9, cpp_type=9, label=3, | ||
146 | default_value=[], | ||
147 | message_type=None, enum_type=None, containing_type=None, | ||
148 | is_extension=False, extension_scope=None, | ||
149 | options=None), | ||
150 | descriptor.FieldDescriptor( | ||
151 | name='cc', full_name='codereview.UploadBundleRequest.cc', index=7, | ||
152 | number=4, type=9, cpp_type=9, label=3, | ||
153 | default_value=[], | ||
154 | message_type=None, enum_type=None, containing_type=None, | ||
155 | is_extension=False, extension_scope=None, | ||
156 | options=None), | ||
157 | ], | ||
158 | extensions=[ | ||
159 | ], | ||
160 | nested_types=[], # TODO(robinson): Implement. | ||
161 | enum_types=[ | ||
162 | ], | ||
163 | options=None) | ||
164 | |||
165 | |||
166 | _UPLOADBUNDLERESPONSE = descriptor.Descriptor( | ||
167 | name='UploadBundleResponse', | ||
168 | full_name='codereview.UploadBundleResponse', | ||
169 | filename='upload_bundle.proto', | ||
170 | containing_type=None, | ||
171 | fields=[ | ||
172 | descriptor.FieldDescriptor( | ||
173 | name='status_code', full_name='codereview.UploadBundleResponse.status_code', index=0, | ||
174 | number=10, type=14, cpp_type=8, label=2, | ||
175 | default_value=1, | ||
176 | message_type=None, enum_type=None, containing_type=None, | ||
177 | is_extension=False, extension_scope=None, | ||
178 | options=None), | ||
179 | descriptor.FieldDescriptor( | ||
180 | name='bundle_id', full_name='codereview.UploadBundleResponse.bundle_id', index=1, | ||
181 | number=11, type=9, cpp_type=9, label=1, | ||
182 | default_value=unicode("", "utf-8"), | ||
183 | message_type=None, enum_type=None, containing_type=None, | ||
184 | is_extension=False, extension_scope=None, | ||
185 | options=None), | ||
186 | descriptor.FieldDescriptor( | ||
187 | name='invalid_reviewers', full_name='codereview.UploadBundleResponse.invalid_reviewers', index=2, | ||
188 | number=12, type=9, cpp_type=9, label=3, | ||
189 | default_value=[], | ||
190 | message_type=None, enum_type=None, containing_type=None, | ||
191 | is_extension=False, extension_scope=None, | ||
192 | options=None), | ||
193 | descriptor.FieldDescriptor( | ||
194 | name='invalid_cc', full_name='codereview.UploadBundleResponse.invalid_cc', index=3, | ||
195 | number=13, type=9, cpp_type=9, label=3, | ||
196 | default_value=[], | ||
197 | message_type=None, enum_type=None, containing_type=None, | ||
198 | is_extension=False, extension_scope=None, | ||
199 | options=None), | ||
200 | ], | ||
201 | extensions=[ | ||
202 | ], | ||
203 | nested_types=[], # TODO(robinson): Implement. | ||
204 | enum_types=[ | ||
205 | _UPLOADBUNDLERESPONSE_CODETYPE, | ||
206 | ], | ||
207 | options=None) | ||
208 | |||
209 | |||
210 | _UPLOADBUNDLECONTINUE = descriptor.Descriptor( | ||
211 | name='UploadBundleContinue', | ||
212 | full_name='codereview.UploadBundleContinue', | ||
213 | filename='upload_bundle.proto', | ||
214 | containing_type=None, | ||
215 | fields=[ | ||
216 | descriptor.FieldDescriptor( | ||
217 | name='bundle_id', full_name='codereview.UploadBundleContinue.bundle_id', index=0, | ||
218 | number=10, type=9, cpp_type=9, label=2, | ||
219 | default_value=unicode("", "utf-8"), | ||
220 | message_type=None, enum_type=None, containing_type=None, | ||
221 | is_extension=False, extension_scope=None, | ||
222 | options=None), | ||
223 | descriptor.FieldDescriptor( | ||
224 | name='segment_id', full_name='codereview.UploadBundleContinue.segment_id', index=1, | ||
225 | number=11, type=5, cpp_type=1, label=2, | ||
226 | default_value=0, | ||
227 | message_type=None, enum_type=None, containing_type=None, | ||
228 | is_extension=False, extension_scope=None, | ||
229 | options=None), | ||
230 | descriptor.FieldDescriptor( | ||
231 | name='partial_upload', full_name='codereview.UploadBundleContinue.partial_upload', index=2, | ||
232 | number=12, type=8, cpp_type=7, label=2, | ||
233 | default_value=False, | ||
234 | message_type=None, enum_type=None, containing_type=None, | ||
235 | is_extension=False, extension_scope=None, | ||
236 | options=None), | ||
237 | descriptor.FieldDescriptor( | ||
238 | name='bundle_data', full_name='codereview.UploadBundleContinue.bundle_data', index=3, | ||
239 | number=13, type=12, cpp_type=9, label=1, | ||
240 | default_value="", | ||
241 | message_type=None, enum_type=None, containing_type=None, | ||
242 | is_extension=False, extension_scope=None, | ||
243 | options=None), | ||
244 | ], | ||
245 | extensions=[ | ||
246 | ], | ||
247 | nested_types=[], # TODO(robinson): Implement. | ||
248 | enum_types=[ | ||
249 | ], | ||
250 | options=None) | ||
251 | |||
252 | |||
253 | _UPLOADBUNDLEREQUEST.fields_by_name['replace'].message_type = _REPLACEPATCHSET | ||
254 | _UPLOADBUNDLERESPONSE.fields_by_name['status_code'].enum_type = _UPLOADBUNDLERESPONSE_CODETYPE | ||
255 | |||
256 | class ReplacePatchSet(message.Message): | ||
257 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
258 | DESCRIPTOR = _REPLACEPATCHSET | ||
259 | |||
260 | class UploadBundleRequest(message.Message): | ||
261 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
262 | DESCRIPTOR = _UPLOADBUNDLEREQUEST | ||
263 | |||
264 | class UploadBundleResponse(message.Message): | ||
265 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
266 | DESCRIPTOR = _UPLOADBUNDLERESPONSE | ||
267 | |||
268 | class UploadBundleContinue(message.Message): | ||
269 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
270 | DESCRIPTOR = _UPLOADBUNDLECONTINUE | ||
271 | |||
diff --git a/froofle/__init__.py b/froofle/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/froofle/__init__.py +++ /dev/null | |||
diff --git a/froofle/protobuf/__init__.py b/froofle/protobuf/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/froofle/protobuf/__init__.py +++ /dev/null | |||
diff --git a/froofle/protobuf/descriptor.py b/froofle/protobuf/descriptor.py deleted file mode 100644 index e74cf25e..00000000 --- a/froofle/protobuf/descriptor.py +++ /dev/null | |||
@@ -1,433 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | # TODO(robinson): We probably need to provide deep-copy methods for | ||
32 | # descriptor types. When a FieldDescriptor is passed into | ||
33 | # Descriptor.__init__(), we should make a deep copy and then set | ||
34 | # containing_type on it. Alternatively, we could just get | ||
35 | # rid of containing_type (iit's not needed for reflection.py, at least). | ||
36 | # | ||
37 | # TODO(robinson): Print method? | ||
38 | # | ||
39 | # TODO(robinson): Useful __repr__? | ||
40 | |||
41 | """Descriptors essentially contain exactly the information found in a .proto | ||
42 | file, in types that make this information accessible in Python. | ||
43 | """ | ||
44 | |||
45 | __author__ = 'robinson@google.com (Will Robinson)' | ||
46 | |||
47 | class DescriptorBase(object): | ||
48 | |||
49 | """Descriptors base class. | ||
50 | |||
51 | This class is the base of all descriptor classes. It provides common options | ||
52 | related functionaility. | ||
53 | """ | ||
54 | |||
55 | def __init__(self, options, options_class_name): | ||
56 | """Initialize the descriptor given its options message and the name of the | ||
57 | class of the options message. The name of the class is required in case | ||
58 | the options message is None and has to be created. | ||
59 | """ | ||
60 | self._options = options | ||
61 | self._options_class_name = options_class_name | ||
62 | |||
63 | def GetOptions(self): | ||
64 | """Retrieves descriptor options. | ||
65 | |||
66 | This method returns the options set or creates the default options for the | ||
67 | descriptor. | ||
68 | """ | ||
69 | if self._options: | ||
70 | return self._options | ||
71 | from froofle.protobuf import descriptor_pb2 | ||
72 | try: | ||
73 | options_class = getattr(descriptor_pb2, self._options_class_name) | ||
74 | except AttributeError: | ||
75 | raise RuntimeError('Unknown options class name %s!' % | ||
76 | (self._options_class_name)) | ||
77 | self._options = options_class() | ||
78 | return self._options | ||
79 | |||
80 | |||
81 | class Descriptor(DescriptorBase): | ||
82 | |||
83 | """Descriptor for a protocol message type. | ||
84 | |||
85 | A Descriptor instance has the following attributes: | ||
86 | |||
87 | name: (str) Name of this protocol message type. | ||
88 | full_name: (str) Fully-qualified name of this protocol message type, | ||
89 | which will include protocol "package" name and the name of any | ||
90 | enclosing types. | ||
91 | |||
92 | filename: (str) Name of the .proto file containing this message. | ||
93 | |||
94 | containing_type: (Descriptor) Reference to the descriptor of the | ||
95 | type containing us, or None if we have no containing type. | ||
96 | |||
97 | fields: (list of FieldDescriptors) Field descriptors for all | ||
98 | fields in this type. | ||
99 | fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor | ||
100 | objects as in |fields|, but indexed by "number" attribute in each | ||
101 | FieldDescriptor. | ||
102 | fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor | ||
103 | objects as in |fields|, but indexed by "name" attribute in each | ||
104 | FieldDescriptor. | ||
105 | |||
106 | nested_types: (list of Descriptors) Descriptor references | ||
107 | for all protocol message types nested within this one. | ||
108 | nested_types_by_name: (dict str -> Descriptor) Same Descriptor | ||
109 | objects as in |nested_types|, but indexed by "name" attribute | ||
110 | in each Descriptor. | ||
111 | |||
112 | enum_types: (list of EnumDescriptors) EnumDescriptor references | ||
113 | for all enums contained within this type. | ||
114 | enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor | ||
115 | objects as in |enum_types|, but indexed by "name" attribute | ||
116 | in each EnumDescriptor. | ||
117 | enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping | ||
118 | from enum value name to EnumValueDescriptor for that value. | ||
119 | |||
120 | extensions: (list of FieldDescriptor) All extensions defined directly | ||
121 | within this message type (NOT within a nested type). | ||
122 | extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor | ||
123 | objects as |extensions|, but indexed by "name" attribute of each | ||
124 | FieldDescriptor. | ||
125 | |||
126 | options: (descriptor_pb2.MessageOptions) Protocol message options or None | ||
127 | to use default message options. | ||
128 | """ | ||
129 | |||
130 | def __init__(self, name, full_name, filename, containing_type, | ||
131 | fields, nested_types, enum_types, extensions, options=None): | ||
132 | """Arguments to __init__() are as described in the description | ||
133 | of Descriptor fields above. | ||
134 | """ | ||
135 | super(Descriptor, self).__init__(options, 'MessageOptions') | ||
136 | self.name = name | ||
137 | self.full_name = full_name | ||
138 | self.filename = filename | ||
139 | self.containing_type = containing_type | ||
140 | |||
141 | # We have fields in addition to fields_by_name and fields_by_number, | ||
142 | # so that: | ||
143 | # 1. Clients can index fields by "order in which they're listed." | ||
144 | # 2. Clients can easily iterate over all fields with the terse | ||
145 | # syntax: for f in descriptor.fields: ... | ||
146 | self.fields = fields | ||
147 | for field in self.fields: | ||
148 | field.containing_type = self | ||
149 | self.fields_by_number = dict((f.number, f) for f in fields) | ||
150 | self.fields_by_name = dict((f.name, f) for f in fields) | ||
151 | |||
152 | self.nested_types = nested_types | ||
153 | self.nested_types_by_name = dict((t.name, t) for t in nested_types) | ||
154 | |||
155 | self.enum_types = enum_types | ||
156 | for enum_type in self.enum_types: | ||
157 | enum_type.containing_type = self | ||
158 | self.enum_types_by_name = dict((t.name, t) for t in enum_types) | ||
159 | self.enum_values_by_name = dict( | ||
160 | (v.name, v) for t in enum_types for v in t.values) | ||
161 | |||
162 | self.extensions = extensions | ||
163 | for extension in self.extensions: | ||
164 | extension.extension_scope = self | ||
165 | self.extensions_by_name = dict((f.name, f) for f in extensions) | ||
166 | |||
167 | |||
168 | # TODO(robinson): We should have aggressive checking here, | ||
169 | # for example: | ||
170 | # * If you specify a repeated field, you should not be allowed | ||
171 | # to specify a default value. | ||
172 | # * [Other examples here as needed]. | ||
173 | # | ||
174 | # TODO(robinson): for this and other *Descriptor classes, we | ||
175 | # might also want to lock things down aggressively (e.g., | ||
176 | # prevent clients from setting the attributes). Having | ||
177 | # stronger invariants here in general will reduce the number | ||
178 | # of runtime checks we must do in reflection.py... | ||
179 | class FieldDescriptor(DescriptorBase): | ||
180 | |||
181 | """Descriptor for a single field in a .proto file. | ||
182 | |||
183 | A FieldDescriptor instance has the following attriubtes: | ||
184 | |||
185 | name: (str) Name of this field, exactly as it appears in .proto. | ||
186 | full_name: (str) Name of this field, including containing scope. This is | ||
187 | particularly relevant for extensions. | ||
188 | index: (int) Dense, 0-indexed index giving the order that this | ||
189 | field textually appears within its message in the .proto file. | ||
190 | number: (int) Tag number declared for this field in the .proto file. | ||
191 | |||
192 | type: (One of the TYPE_* constants below) Declared type. | ||
193 | cpp_type: (One of the CPPTYPE_* constants below) C++ type used to | ||
194 | represent this field. | ||
195 | |||
196 | label: (One of the LABEL_* constants below) Tells whether this | ||
197 | field is optional, required, or repeated. | ||
198 | default_value: (Varies) Default value of this field. Only | ||
199 | meaningful for non-repeated scalar fields. Repeated fields | ||
200 | should always set this to [], and non-repeated composite | ||
201 | fields should always set this to None. | ||
202 | |||
203 | containing_type: (Descriptor) Descriptor of the protocol message | ||
204 | type that contains this field. Set by the Descriptor constructor | ||
205 | if we're passed into one. | ||
206 | Somewhat confusingly, for extension fields, this is the | ||
207 | descriptor of the EXTENDED message, not the descriptor | ||
208 | of the message containing this field. (See is_extension and | ||
209 | extension_scope below). | ||
210 | message_type: (Descriptor) If a composite field, a descriptor | ||
211 | of the message type contained in this field. Otherwise, this is None. | ||
212 | enum_type: (EnumDescriptor) If this field contains an enum, a | ||
213 | descriptor of that enum. Otherwise, this is None. | ||
214 | |||
215 | is_extension: True iff this describes an extension field. | ||
216 | extension_scope: (Descriptor) Only meaningful if is_extension is True. | ||
217 | Gives the message that immediately contains this extension field. | ||
218 | Will be None iff we're a top-level (file-level) extension field. | ||
219 | |||
220 | options: (descriptor_pb2.FieldOptions) Protocol message field options or | ||
221 | None to use default field options. | ||
222 | """ | ||
223 | |||
224 | # Must be consistent with C++ FieldDescriptor::Type enum in | ||
225 | # descriptor.h. | ||
226 | # | ||
227 | # TODO(robinson): Find a way to eliminate this repetition. | ||
228 | TYPE_DOUBLE = 1 | ||
229 | TYPE_FLOAT = 2 | ||
230 | TYPE_INT64 = 3 | ||
231 | TYPE_UINT64 = 4 | ||
232 | TYPE_INT32 = 5 | ||
233 | TYPE_FIXED64 = 6 | ||
234 | TYPE_FIXED32 = 7 | ||
235 | TYPE_BOOL = 8 | ||
236 | TYPE_STRING = 9 | ||
237 | TYPE_GROUP = 10 | ||
238 | TYPE_MESSAGE = 11 | ||
239 | TYPE_BYTES = 12 | ||
240 | TYPE_UINT32 = 13 | ||
241 | TYPE_ENUM = 14 | ||
242 | TYPE_SFIXED32 = 15 | ||
243 | TYPE_SFIXED64 = 16 | ||
244 | TYPE_SINT32 = 17 | ||
245 | TYPE_SINT64 = 18 | ||
246 | MAX_TYPE = 18 | ||
247 | |||
248 | # Must be consistent with C++ FieldDescriptor::CppType enum in | ||
249 | # descriptor.h. | ||
250 | # | ||
251 | # TODO(robinson): Find a way to eliminate this repetition. | ||
252 | CPPTYPE_INT32 = 1 | ||
253 | CPPTYPE_INT64 = 2 | ||
254 | CPPTYPE_UINT32 = 3 | ||
255 | CPPTYPE_UINT64 = 4 | ||
256 | CPPTYPE_DOUBLE = 5 | ||
257 | CPPTYPE_FLOAT = 6 | ||
258 | CPPTYPE_BOOL = 7 | ||
259 | CPPTYPE_ENUM = 8 | ||
260 | CPPTYPE_STRING = 9 | ||
261 | CPPTYPE_MESSAGE = 10 | ||
262 | MAX_CPPTYPE = 10 | ||
263 | |||
264 | # Must be consistent with C++ FieldDescriptor::Label enum in | ||
265 | # descriptor.h. | ||
266 | # | ||
267 | # TODO(robinson): Find a way to eliminate this repetition. | ||
268 | LABEL_OPTIONAL = 1 | ||
269 | LABEL_REQUIRED = 2 | ||
270 | LABEL_REPEATED = 3 | ||
271 | MAX_LABEL = 3 | ||
272 | |||
273 | def __init__(self, name, full_name, index, number, type, cpp_type, label, | ||
274 | default_value, message_type, enum_type, containing_type, | ||
275 | is_extension, extension_scope, options=None): | ||
276 | """The arguments are as described in the description of FieldDescriptor | ||
277 | attributes above. | ||
278 | |||
279 | Note that containing_type may be None, and may be set later if necessary | ||
280 | (to deal with circular references between message types, for example). | ||
281 | Likewise for extension_scope. | ||
282 | """ | ||
283 | super(FieldDescriptor, self).__init__(options, 'FieldOptions') | ||
284 | self.name = name | ||
285 | self.full_name = full_name | ||
286 | self.index = index | ||
287 | self.number = number | ||
288 | self.type = type | ||
289 | self.cpp_type = cpp_type | ||
290 | self.label = label | ||
291 | self.default_value = default_value | ||
292 | self.containing_type = containing_type | ||
293 | self.message_type = message_type | ||
294 | self.enum_type = enum_type | ||
295 | self.is_extension = is_extension | ||
296 | self.extension_scope = extension_scope | ||
297 | |||
298 | |||
299 | class EnumDescriptor(DescriptorBase): | ||
300 | |||
301 | """Descriptor for an enum defined in a .proto file. | ||
302 | |||
303 | An EnumDescriptor instance has the following attributes: | ||
304 | |||
305 | name: (str) Name of the enum type. | ||
306 | full_name: (str) Full name of the type, including package name | ||
307 | and any enclosing type(s). | ||
308 | filename: (str) Name of the .proto file in which this appears. | ||
309 | |||
310 | values: (list of EnumValueDescriptors) List of the values | ||
311 | in this enum. | ||
312 | values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, | ||
313 | but indexed by the "name" field of each EnumValueDescriptor. | ||
314 | values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, | ||
315 | but indexed by the "number" field of each EnumValueDescriptor. | ||
316 | containing_type: (Descriptor) Descriptor of the immediate containing | ||
317 | type of this enum, or None if this is an enum defined at the | ||
318 | top level in a .proto file. Set by Descriptor's constructor | ||
319 | if we're passed into one. | ||
320 | options: (descriptor_pb2.EnumOptions) Enum options message or | ||
321 | None to use default enum options. | ||
322 | """ | ||
323 | |||
324 | def __init__(self, name, full_name, filename, values, | ||
325 | containing_type=None, options=None): | ||
326 | """Arguments are as described in the attribute description above.""" | ||
327 | super(EnumDescriptor, self).__init__(options, 'EnumOptions') | ||
328 | self.name = name | ||
329 | self.full_name = full_name | ||
330 | self.filename = filename | ||
331 | self.values = values | ||
332 | for value in self.values: | ||
333 | value.type = self | ||
334 | self.values_by_name = dict((v.name, v) for v in values) | ||
335 | self.values_by_number = dict((v.number, v) for v in values) | ||
336 | self.containing_type = containing_type | ||
337 | |||
338 | |||
339 | class EnumValueDescriptor(DescriptorBase): | ||
340 | |||
341 | """Descriptor for a single value within an enum. | ||
342 | |||
343 | name: (str) Name of this value. | ||
344 | index: (int) Dense, 0-indexed index giving the order that this | ||
345 | value appears textually within its enum in the .proto file. | ||
346 | number: (int) Actual number assigned to this enum value. | ||
347 | type: (EnumDescriptor) EnumDescriptor to which this value | ||
348 | belongs. Set by EnumDescriptor's constructor if we're | ||
349 | passed into one. | ||
350 | options: (descriptor_pb2.EnumValueOptions) Enum value options message or | ||
351 | None to use default enum value options options. | ||
352 | """ | ||
353 | |||
354 | def __init__(self, name, index, number, type=None, options=None): | ||
355 | """Arguments are as described in the attribute description above.""" | ||
356 | super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions') | ||
357 | self.name = name | ||
358 | self.index = index | ||
359 | self.number = number | ||
360 | self.type = type | ||
361 | |||
362 | |||
363 | class ServiceDescriptor(DescriptorBase): | ||
364 | |||
365 | """Descriptor for a service. | ||
366 | |||
367 | name: (str) Name of the service. | ||
368 | full_name: (str) Full name of the service, including package name. | ||
369 | index: (int) 0-indexed index giving the order that this services | ||
370 | definition appears withing the .proto file. | ||
371 | methods: (list of MethodDescriptor) List of methods provided by this | ||
372 | service. | ||
373 | options: (descriptor_pb2.ServiceOptions) Service options message or | ||
374 | None to use default service options. | ||
375 | """ | ||
376 | |||
377 | def __init__(self, name, full_name, index, methods, options=None): | ||
378 | super(ServiceDescriptor, self).__init__(options, 'ServiceOptions') | ||
379 | self.name = name | ||
380 | self.full_name = full_name | ||
381 | self.index = index | ||
382 | self.methods = methods | ||
383 | # Set the containing service for each method in this service. | ||
384 | for method in self.methods: | ||
385 | method.containing_service = self | ||
386 | |||
387 | def FindMethodByName(self, name): | ||
388 | """Searches for the specified method, and returns its descriptor.""" | ||
389 | for method in self.methods: | ||
390 | if name == method.name: | ||
391 | return method | ||
392 | return None | ||
393 | |||
394 | |||
395 | class MethodDescriptor(DescriptorBase): | ||
396 | |||
397 | """Descriptor for a method in a service. | ||
398 | |||
399 | name: (str) Name of the method within the service. | ||
400 | full_name: (str) Full name of method. | ||
401 | index: (int) 0-indexed index of the method inside the service. | ||
402 | containing_service: (ServiceDescriptor) The service that contains this | ||
403 | method. | ||
404 | input_type: The descriptor of the message that this method accepts. | ||
405 | output_type: The descriptor of the message that this method returns. | ||
406 | options: (descriptor_pb2.MethodOptions) Method options message or | ||
407 | None to use default method options. | ||
408 | """ | ||
409 | |||
410 | def __init__(self, name, full_name, index, containing_service, | ||
411 | input_type, output_type, options=None): | ||
412 | """The arguments are as described in the description of MethodDescriptor | ||
413 | attributes above. | ||
414 | |||
415 | Note that containing_service may be None, and may be set later if necessary. | ||
416 | """ | ||
417 | super(MethodDescriptor, self).__init__(options, 'MethodOptions') | ||
418 | self.name = name | ||
419 | self.full_name = full_name | ||
420 | self.index = index | ||
421 | self.containing_service = containing_service | ||
422 | self.input_type = input_type | ||
423 | self.output_type = output_type | ||
424 | |||
425 | |||
426 | def _ParseOptions(message, string): | ||
427 | """Parses serialized options. | ||
428 | |||
429 | This helper function is used to parse serialized options in generated | ||
430 | proto2 files. It must not be used outside proto2. | ||
431 | """ | ||
432 | message.ParseFromString(string) | ||
433 | return message; | ||
diff --git a/froofle/protobuf/descriptor_pb2.py b/froofle/protobuf/descriptor_pb2.py deleted file mode 100644 index 16873834..00000000 --- a/froofle/protobuf/descriptor_pb2.py +++ /dev/null | |||
@@ -1,950 +0,0 @@ | |||
1 | #!/usr/bin/python2.4 | ||
2 | # Generated by the protocol buffer compiler. DO NOT EDIT! | ||
3 | |||
4 | from froofle.protobuf import descriptor | ||
5 | from froofle.protobuf import message | ||
6 | from froofle.protobuf import reflection | ||
7 | from froofle.protobuf import service | ||
8 | from froofle.protobuf import service_reflection | ||
9 | |||
10 | |||
11 | _FIELDDESCRIPTORPROTO_TYPE = descriptor.EnumDescriptor( | ||
12 | name='Type', | ||
13 | full_name='froofle.protobuf.FieldDescriptorProto.Type', | ||
14 | filename='Type', | ||
15 | values=[ | ||
16 | descriptor.EnumValueDescriptor( | ||
17 | name='TYPE_DOUBLE', index=0, number=1, | ||
18 | options=None, | ||
19 | type=None), | ||
20 | descriptor.EnumValueDescriptor( | ||
21 | name='TYPE_FLOAT', index=1, number=2, | ||
22 | options=None, | ||
23 | type=None), | ||
24 | descriptor.EnumValueDescriptor( | ||
25 | name='TYPE_INT64', index=2, number=3, | ||
26 | options=None, | ||
27 | type=None), | ||
28 | descriptor.EnumValueDescriptor( | ||
29 | name='TYPE_UINT64', index=3, number=4, | ||
30 | options=None, | ||
31 | type=None), | ||
32 | descriptor.EnumValueDescriptor( | ||
33 | name='TYPE_INT32', index=4, number=5, | ||
34 | options=None, | ||
35 | type=None), | ||
36 | descriptor.EnumValueDescriptor( | ||
37 | name='TYPE_FIXED64', index=5, number=6, | ||
38 | options=None, | ||
39 | type=None), | ||
40 | descriptor.EnumValueDescriptor( | ||
41 | name='TYPE_FIXED32', index=6, number=7, | ||
42 | options=None, | ||
43 | type=None), | ||
44 | descriptor.EnumValueDescriptor( | ||
45 | name='TYPE_BOOL', index=7, number=8, | ||
46 | options=None, | ||
47 | type=None), | ||
48 | descriptor.EnumValueDescriptor( | ||
49 | name='TYPE_STRING', index=8, number=9, | ||
50 | options=None, | ||
51 | type=None), | ||
52 | descriptor.EnumValueDescriptor( | ||
53 | name='TYPE_GROUP', index=9, number=10, | ||
54 | options=None, | ||
55 | type=None), | ||
56 | descriptor.EnumValueDescriptor( | ||
57 | name='TYPE_MESSAGE', index=10, number=11, | ||
58 | options=None, | ||
59 | type=None), | ||
60 | descriptor.EnumValueDescriptor( | ||
61 | name='TYPE_BYTES', index=11, number=12, | ||
62 | options=None, | ||
63 | type=None), | ||
64 | descriptor.EnumValueDescriptor( | ||
65 | name='TYPE_UINT32', index=12, number=13, | ||
66 | options=None, | ||
67 | type=None), | ||
68 | descriptor.EnumValueDescriptor( | ||
69 | name='TYPE_ENUM', index=13, number=14, | ||
70 | options=None, | ||
71 | type=None), | ||
72 | descriptor.EnumValueDescriptor( | ||
73 | name='TYPE_SFIXED32', index=14, number=15, | ||
74 | options=None, | ||
75 | type=None), | ||
76 | descriptor.EnumValueDescriptor( | ||
77 | name='TYPE_SFIXED64', index=15, number=16, | ||
78 | options=None, | ||
79 | type=None), | ||
80 | descriptor.EnumValueDescriptor( | ||
81 | name='TYPE_SINT32', index=16, number=17, | ||
82 | options=None, | ||
83 | type=None), | ||
84 | descriptor.EnumValueDescriptor( | ||
85 | name='TYPE_SINT64', index=17, number=18, | ||
86 | options=None, | ||
87 | type=None), | ||
88 | ], | ||
89 | options=None, | ||
90 | ) | ||
91 | |||
92 | _FIELDDESCRIPTORPROTO_LABEL = descriptor.EnumDescriptor( | ||
93 | name='Label', | ||
94 | full_name='froofle.protobuf.FieldDescriptorProto.Label', | ||
95 | filename='Label', | ||
96 | values=[ | ||
97 | descriptor.EnumValueDescriptor( | ||
98 | name='LABEL_OPTIONAL', index=0, number=1, | ||
99 | options=None, | ||
100 | type=None), | ||
101 | descriptor.EnumValueDescriptor( | ||
102 | name='LABEL_REQUIRED', index=1, number=2, | ||
103 | options=None, | ||
104 | type=None), | ||
105 | descriptor.EnumValueDescriptor( | ||
106 | name='LABEL_REPEATED', index=2, number=3, | ||
107 | options=None, | ||
108 | type=None), | ||
109 | ], | ||
110 | options=None, | ||
111 | ) | ||
112 | |||
113 | _FILEOPTIONS_OPTIMIZEMODE = descriptor.EnumDescriptor( | ||
114 | name='OptimizeMode', | ||
115 | full_name='froofle.protobuf.FileOptions.OptimizeMode', | ||
116 | filename='OptimizeMode', | ||
117 | values=[ | ||
118 | descriptor.EnumValueDescriptor( | ||
119 | name='SPEED', index=0, number=1, | ||
120 | options=None, | ||
121 | type=None), | ||
122 | descriptor.EnumValueDescriptor( | ||
123 | name='CODE_SIZE', index=1, number=2, | ||
124 | options=None, | ||
125 | type=None), | ||
126 | ], | ||
127 | options=None, | ||
128 | ) | ||
129 | |||
130 | _FIELDOPTIONS_CTYPE = descriptor.EnumDescriptor( | ||
131 | name='CType', | ||
132 | full_name='froofle.protobuf.FieldOptions.CType', | ||
133 | filename='CType', | ||
134 | values=[ | ||
135 | descriptor.EnumValueDescriptor( | ||
136 | name='CORD', index=0, number=1, | ||
137 | options=None, | ||
138 | type=None), | ||
139 | descriptor.EnumValueDescriptor( | ||
140 | name='STRING_PIECE', index=1, number=2, | ||
141 | options=None, | ||
142 | type=None), | ||
143 | ], | ||
144 | options=None, | ||
145 | ) | ||
146 | |||
147 | |||
148 | _FILEDESCRIPTORSET = descriptor.Descriptor( | ||
149 | name='FileDescriptorSet', | ||
150 | full_name='froofle.protobuf.FileDescriptorSet', | ||
151 | filename='froofle/protobuf/descriptor.proto', | ||
152 | containing_type=None, | ||
153 | fields=[ | ||
154 | descriptor.FieldDescriptor( | ||
155 | name='file', full_name='froofle.protobuf.FileDescriptorSet.file', index=0, | ||
156 | number=1, type=11, cpp_type=10, label=3, | ||
157 | default_value=[], | ||
158 | message_type=None, enum_type=None, containing_type=None, | ||
159 | is_extension=False, extension_scope=None, | ||
160 | options=None), | ||
161 | ], | ||
162 | extensions=[ | ||
163 | ], | ||
164 | nested_types=[], # TODO(robinson): Implement. | ||
165 | enum_types=[ | ||
166 | ], | ||
167 | options=None) | ||
168 | |||
169 | |||
170 | _FILEDESCRIPTORPROTO = descriptor.Descriptor( | ||
171 | name='FileDescriptorProto', | ||
172 | full_name='froofle.protobuf.FileDescriptorProto', | ||
173 | filename='froofle/protobuf/descriptor.proto', | ||
174 | containing_type=None, | ||
175 | fields=[ | ||
176 | descriptor.FieldDescriptor( | ||
177 | name='name', full_name='froofle.protobuf.FileDescriptorProto.name', index=0, | ||
178 | number=1, type=9, cpp_type=9, label=1, | ||
179 | default_value=unicode("", "utf-8"), | ||
180 | message_type=None, enum_type=None, containing_type=None, | ||
181 | is_extension=False, extension_scope=None, | ||
182 | options=None), | ||
183 | descriptor.FieldDescriptor( | ||
184 | name='package', full_name='froofle.protobuf.FileDescriptorProto.package', index=1, | ||
185 | number=2, type=9, cpp_type=9, label=1, | ||
186 | default_value=unicode("", "utf-8"), | ||
187 | message_type=None, enum_type=None, containing_type=None, | ||
188 | is_extension=False, extension_scope=None, | ||
189 | options=None), | ||
190 | descriptor.FieldDescriptor( | ||
191 | name='dependency', full_name='froofle.protobuf.FileDescriptorProto.dependency', index=2, | ||
192 | number=3, type=9, cpp_type=9, label=3, | ||
193 | default_value=[], | ||
194 | message_type=None, enum_type=None, containing_type=None, | ||
195 | is_extension=False, extension_scope=None, | ||
196 | options=None), | ||
197 | descriptor.FieldDescriptor( | ||
198 | name='message_type', full_name='froofle.protobuf.FileDescriptorProto.message_type', index=3, | ||
199 | number=4, type=11, cpp_type=10, label=3, | ||
200 | default_value=[], | ||
201 | message_type=None, enum_type=None, containing_type=None, | ||
202 | is_extension=False, extension_scope=None, | ||
203 | options=None), | ||
204 | descriptor.FieldDescriptor( | ||
205 | name='enum_type', full_name='froofle.protobuf.FileDescriptorProto.enum_type', index=4, | ||
206 | number=5, type=11, cpp_type=10, label=3, | ||
207 | default_value=[], | ||
208 | message_type=None, enum_type=None, containing_type=None, | ||
209 | is_extension=False, extension_scope=None, | ||
210 | options=None), | ||
211 | descriptor.FieldDescriptor( | ||
212 | name='service', full_name='froofle.protobuf.FileDescriptorProto.service', index=5, | ||
213 | number=6, type=11, cpp_type=10, label=3, | ||
214 | default_value=[], | ||
215 | message_type=None, enum_type=None, containing_type=None, | ||
216 | is_extension=False, extension_scope=None, | ||
217 | options=None), | ||
218 | descriptor.FieldDescriptor( | ||
219 | name='extension', full_name='froofle.protobuf.FileDescriptorProto.extension', index=6, | ||
220 | number=7, type=11, cpp_type=10, label=3, | ||
221 | default_value=[], | ||
222 | message_type=None, enum_type=None, containing_type=None, | ||
223 | is_extension=False, extension_scope=None, | ||
224 | options=None), | ||
225 | descriptor.FieldDescriptor( | ||
226 | name='options', full_name='froofle.protobuf.FileDescriptorProto.options', index=7, | ||
227 | number=8, type=11, cpp_type=10, label=1, | ||
228 | default_value=None, | ||
229 | message_type=None, enum_type=None, containing_type=None, | ||
230 | is_extension=False, extension_scope=None, | ||
231 | options=None), | ||
232 | ], | ||
233 | extensions=[ | ||
234 | ], | ||
235 | nested_types=[], # TODO(robinson): Implement. | ||
236 | enum_types=[ | ||
237 | ], | ||
238 | options=None) | ||
239 | |||
240 | |||
241 | _DESCRIPTORPROTO_EXTENSIONRANGE = descriptor.Descriptor( | ||
242 | name='ExtensionRange', | ||
243 | full_name='froofle.protobuf.DescriptorProto.ExtensionRange', | ||
244 | filename='froofle/protobuf/descriptor.proto', | ||
245 | containing_type=None, | ||
246 | fields=[ | ||
247 | descriptor.FieldDescriptor( | ||
248 | name='start', full_name='froofle.protobuf.DescriptorProto.ExtensionRange.start', index=0, | ||
249 | number=1, type=5, cpp_type=1, label=1, | ||
250 | default_value=0, | ||
251 | message_type=None, enum_type=None, containing_type=None, | ||
252 | is_extension=False, extension_scope=None, | ||
253 | options=None), | ||
254 | descriptor.FieldDescriptor( | ||
255 | name='end', full_name='froofle.protobuf.DescriptorProto.ExtensionRange.end', index=1, | ||
256 | number=2, type=5, cpp_type=1, label=1, | ||
257 | default_value=0, | ||
258 | message_type=None, enum_type=None, containing_type=None, | ||
259 | is_extension=False, extension_scope=None, | ||
260 | options=None), | ||
261 | ], | ||
262 | extensions=[ | ||
263 | ], | ||
264 | nested_types=[], # TODO(robinson): Implement. | ||
265 | enum_types=[ | ||
266 | ], | ||
267 | options=None) | ||
268 | |||
269 | _DESCRIPTORPROTO = descriptor.Descriptor( | ||
270 | name='DescriptorProto', | ||
271 | full_name='froofle.protobuf.DescriptorProto', | ||
272 | filename='froofle/protobuf/descriptor.proto', | ||
273 | containing_type=None, | ||
274 | fields=[ | ||
275 | descriptor.FieldDescriptor( | ||
276 | name='name', full_name='froofle.protobuf.DescriptorProto.name', index=0, | ||
277 | number=1, type=9, cpp_type=9, label=1, | ||
278 | default_value=unicode("", "utf-8"), | ||
279 | message_type=None, enum_type=None, containing_type=None, | ||
280 | is_extension=False, extension_scope=None, | ||
281 | options=None), | ||
282 | descriptor.FieldDescriptor( | ||
283 | name='field', full_name='froofle.protobuf.DescriptorProto.field', index=1, | ||
284 | number=2, type=11, cpp_type=10, label=3, | ||
285 | default_value=[], | ||
286 | message_type=None, enum_type=None, containing_type=None, | ||
287 | is_extension=False, extension_scope=None, | ||
288 | options=None), | ||
289 | descriptor.FieldDescriptor( | ||
290 | name='extension', full_name='froofle.protobuf.DescriptorProto.extension', index=2, | ||
291 | number=6, type=11, cpp_type=10, label=3, | ||
292 | default_value=[], | ||
293 | message_type=None, enum_type=None, containing_type=None, | ||
294 | is_extension=False, extension_scope=None, | ||
295 | options=None), | ||
296 | descriptor.FieldDescriptor( | ||
297 | name='nested_type', full_name='froofle.protobuf.DescriptorProto.nested_type', index=3, | ||
298 | number=3, type=11, cpp_type=10, label=3, | ||
299 | default_value=[], | ||
300 | message_type=None, enum_type=None, containing_type=None, | ||
301 | is_extension=False, extension_scope=None, | ||
302 | options=None), | ||
303 | descriptor.FieldDescriptor( | ||
304 | name='enum_type', full_name='froofle.protobuf.DescriptorProto.enum_type', index=4, | ||
305 | number=4, type=11, cpp_type=10, label=3, | ||
306 | default_value=[], | ||
307 | message_type=None, enum_type=None, containing_type=None, | ||
308 | is_extension=False, extension_scope=None, | ||
309 | options=None), | ||
310 | descriptor.FieldDescriptor( | ||
311 | name='extension_range', full_name='froofle.protobuf.DescriptorProto.extension_range', index=5, | ||
312 | number=5, type=11, cpp_type=10, label=3, | ||
313 | default_value=[], | ||
314 | message_type=None, enum_type=None, containing_type=None, | ||
315 | is_extension=False, extension_scope=None, | ||
316 | options=None), | ||
317 | descriptor.FieldDescriptor( | ||
318 | name='options', full_name='froofle.protobuf.DescriptorProto.options', index=6, | ||
319 | number=7, type=11, cpp_type=10, label=1, | ||
320 | default_value=None, | ||
321 | message_type=None, enum_type=None, containing_type=None, | ||
322 | is_extension=False, extension_scope=None, | ||
323 | options=None), | ||
324 | ], | ||
325 | extensions=[ | ||
326 | ], | ||
327 | nested_types=[], # TODO(robinson): Implement. | ||
328 | enum_types=[ | ||
329 | ], | ||
330 | options=None) | ||
331 | |||
332 | |||
333 | _FIELDDESCRIPTORPROTO = descriptor.Descriptor( | ||
334 | name='FieldDescriptorProto', | ||
335 | full_name='froofle.protobuf.FieldDescriptorProto', | ||
336 | filename='froofle/protobuf/descriptor.proto', | ||
337 | containing_type=None, | ||
338 | fields=[ | ||
339 | descriptor.FieldDescriptor( | ||
340 | name='name', full_name='froofle.protobuf.FieldDescriptorProto.name', index=0, | ||
341 | number=1, type=9, cpp_type=9, label=1, | ||
342 | default_value=unicode("", "utf-8"), | ||
343 | message_type=None, enum_type=None, containing_type=None, | ||
344 | is_extension=False, extension_scope=None, | ||
345 | options=None), | ||
346 | descriptor.FieldDescriptor( | ||
347 | name='number', full_name='froofle.protobuf.FieldDescriptorProto.number', index=1, | ||
348 | number=3, type=5, cpp_type=1, label=1, | ||
349 | default_value=0, | ||
350 | message_type=None, enum_type=None, containing_type=None, | ||
351 | is_extension=False, extension_scope=None, | ||
352 | options=None), | ||
353 | descriptor.FieldDescriptor( | ||
354 | name='label', full_name='froofle.protobuf.FieldDescriptorProto.label', index=2, | ||
355 | number=4, type=14, cpp_type=8, label=1, | ||
356 | default_value=1, | ||
357 | message_type=None, enum_type=None, containing_type=None, | ||
358 | is_extension=False, extension_scope=None, | ||
359 | options=None), | ||
360 | descriptor.FieldDescriptor( | ||
361 | name='type', full_name='froofle.protobuf.FieldDescriptorProto.type', index=3, | ||
362 | number=5, type=14, cpp_type=8, label=1, | ||
363 | default_value=1, | ||
364 | message_type=None, enum_type=None, containing_type=None, | ||
365 | is_extension=False, extension_scope=None, | ||
366 | options=None), | ||
367 | descriptor.FieldDescriptor( | ||
368 | name='type_name', full_name='froofle.protobuf.FieldDescriptorProto.type_name', index=4, | ||
369 | number=6, type=9, cpp_type=9, label=1, | ||
370 | default_value=unicode("", "utf-8"), | ||
371 | message_type=None, enum_type=None, containing_type=None, | ||
372 | is_extension=False, extension_scope=None, | ||
373 | options=None), | ||
374 | descriptor.FieldDescriptor( | ||
375 | name='extendee', full_name='froofle.protobuf.FieldDescriptorProto.extendee', index=5, | ||
376 | number=2, type=9, cpp_type=9, label=1, | ||
377 | default_value=unicode("", "utf-8"), | ||
378 | message_type=None, enum_type=None, containing_type=None, | ||
379 | is_extension=False, extension_scope=None, | ||
380 | options=None), | ||
381 | descriptor.FieldDescriptor( | ||
382 | name='default_value', full_name='froofle.protobuf.FieldDescriptorProto.default_value', index=6, | ||
383 | number=7, type=9, cpp_type=9, label=1, | ||
384 | default_value=unicode("", "utf-8"), | ||
385 | message_type=None, enum_type=None, containing_type=None, | ||
386 | is_extension=False, extension_scope=None, | ||
387 | options=None), | ||
388 | descriptor.FieldDescriptor( | ||
389 | name='options', full_name='froofle.protobuf.FieldDescriptorProto.options', index=7, | ||
390 | number=8, type=11, cpp_type=10, label=1, | ||
391 | default_value=None, | ||
392 | message_type=None, enum_type=None, containing_type=None, | ||
393 | is_extension=False, extension_scope=None, | ||
394 | options=None), | ||
395 | ], | ||
396 | extensions=[ | ||
397 | ], | ||
398 | nested_types=[], # TODO(robinson): Implement. | ||
399 | enum_types=[ | ||
400 | _FIELDDESCRIPTORPROTO_TYPE, | ||
401 | _FIELDDESCRIPTORPROTO_LABEL, | ||
402 | ], | ||
403 | options=None) | ||
404 | |||
405 | |||
406 | _ENUMDESCRIPTORPROTO = descriptor.Descriptor( | ||
407 | name='EnumDescriptorProto', | ||
408 | full_name='froofle.protobuf.EnumDescriptorProto', | ||
409 | filename='froofle/protobuf/descriptor.proto', | ||
410 | containing_type=None, | ||
411 | fields=[ | ||
412 | descriptor.FieldDescriptor( | ||
413 | name='name', full_name='froofle.protobuf.EnumDescriptorProto.name', index=0, | ||
414 | number=1, type=9, cpp_type=9, label=1, | ||
415 | default_value=unicode("", "utf-8"), | ||
416 | message_type=None, enum_type=None, containing_type=None, | ||
417 | is_extension=False, extension_scope=None, | ||
418 | options=None), | ||
419 | descriptor.FieldDescriptor( | ||
420 | name='value', full_name='froofle.protobuf.EnumDescriptorProto.value', index=1, | ||
421 | number=2, type=11, cpp_type=10, label=3, | ||
422 | default_value=[], | ||
423 | message_type=None, enum_type=None, containing_type=None, | ||
424 | is_extension=False, extension_scope=None, | ||
425 | options=None), | ||
426 | descriptor.FieldDescriptor( | ||
427 | name='options', full_name='froofle.protobuf.EnumDescriptorProto.options', index=2, | ||
428 | number=3, type=11, cpp_type=10, label=1, | ||
429 | default_value=None, | ||
430 | message_type=None, enum_type=None, containing_type=None, | ||
431 | is_extension=False, extension_scope=None, | ||
432 | options=None), | ||
433 | ], | ||
434 | extensions=[ | ||
435 | ], | ||
436 | nested_types=[], # TODO(robinson): Implement. | ||
437 | enum_types=[ | ||
438 | ], | ||
439 | options=None) | ||
440 | |||
441 | |||
442 | _ENUMVALUEDESCRIPTORPROTO = descriptor.Descriptor( | ||
443 | name='EnumValueDescriptorProto', | ||
444 | full_name='froofle.protobuf.EnumValueDescriptorProto', | ||
445 | filename='froofle/protobuf/descriptor.proto', | ||
446 | containing_type=None, | ||
447 | fields=[ | ||
448 | descriptor.FieldDescriptor( | ||
449 | name='name', full_name='froofle.protobuf.EnumValueDescriptorProto.name', index=0, | ||
450 | number=1, type=9, cpp_type=9, label=1, | ||
451 | default_value=unicode("", "utf-8"), | ||
452 | message_type=None, enum_type=None, containing_type=None, | ||
453 | is_extension=False, extension_scope=None, | ||
454 | options=None), | ||
455 | descriptor.FieldDescriptor( | ||
456 | name='number', full_name='froofle.protobuf.EnumValueDescriptorProto.number', index=1, | ||
457 | number=2, type=5, cpp_type=1, label=1, | ||
458 | default_value=0, | ||
459 | message_type=None, enum_type=None, containing_type=None, | ||
460 | is_extension=False, extension_scope=None, | ||
461 | options=None), | ||
462 | descriptor.FieldDescriptor( | ||
463 | name='options', full_name='froofle.protobuf.EnumValueDescriptorProto.options', index=2, | ||
464 | number=3, type=11, cpp_type=10, label=1, | ||
465 | default_value=None, | ||
466 | message_type=None, enum_type=None, containing_type=None, | ||
467 | is_extension=False, extension_scope=None, | ||
468 | options=None), | ||
469 | ], | ||
470 | extensions=[ | ||
471 | ], | ||
472 | nested_types=[], # TODO(robinson): Implement. | ||
473 | enum_types=[ | ||
474 | ], | ||
475 | options=None) | ||
476 | |||
477 | |||
478 | _SERVICEDESCRIPTORPROTO = descriptor.Descriptor( | ||
479 | name='ServiceDescriptorProto', | ||
480 | full_name='froofle.protobuf.ServiceDescriptorProto', | ||
481 | filename='froofle/protobuf/descriptor.proto', | ||
482 | containing_type=None, | ||
483 | fields=[ | ||
484 | descriptor.FieldDescriptor( | ||
485 | name='name', full_name='froofle.protobuf.ServiceDescriptorProto.name', index=0, | ||
486 | number=1, type=9, cpp_type=9, label=1, | ||
487 | default_value=unicode("", "utf-8"), | ||
488 | message_type=None, enum_type=None, containing_type=None, | ||
489 | is_extension=False, extension_scope=None, | ||
490 | options=None), | ||
491 | descriptor.FieldDescriptor( | ||
492 | name='method', full_name='froofle.protobuf.ServiceDescriptorProto.method', index=1, | ||
493 | number=2, type=11, cpp_type=10, label=3, | ||
494 | default_value=[], | ||
495 | message_type=None, enum_type=None, containing_type=None, | ||
496 | is_extension=False, extension_scope=None, | ||
497 | options=None), | ||
498 | descriptor.FieldDescriptor( | ||
499 | name='options', full_name='froofle.protobuf.ServiceDescriptorProto.options', index=2, | ||
500 | number=3, type=11, cpp_type=10, label=1, | ||
501 | default_value=None, | ||
502 | message_type=None, enum_type=None, containing_type=None, | ||
503 | is_extension=False, extension_scope=None, | ||
504 | options=None), | ||
505 | ], | ||
506 | extensions=[ | ||
507 | ], | ||
508 | nested_types=[], # TODO(robinson): Implement. | ||
509 | enum_types=[ | ||
510 | ], | ||
511 | options=None) | ||
512 | |||
513 | |||
514 | _METHODDESCRIPTORPROTO = descriptor.Descriptor( | ||
515 | name='MethodDescriptorProto', | ||
516 | full_name='froofle.protobuf.MethodDescriptorProto', | ||
517 | filename='froofle/protobuf/descriptor.proto', | ||
518 | containing_type=None, | ||
519 | fields=[ | ||
520 | descriptor.FieldDescriptor( | ||
521 | name='name', full_name='froofle.protobuf.MethodDescriptorProto.name', index=0, | ||
522 | number=1, type=9, cpp_type=9, label=1, | ||
523 | default_value=unicode("", "utf-8"), | ||
524 | message_type=None, enum_type=None, containing_type=None, | ||
525 | is_extension=False, extension_scope=None, | ||
526 | options=None), | ||
527 | descriptor.FieldDescriptor( | ||
528 | name='input_type', full_name='froofle.protobuf.MethodDescriptorProto.input_type', index=1, | ||
529 | number=2, type=9, cpp_type=9, label=1, | ||
530 | default_value=unicode("", "utf-8"), | ||
531 | message_type=None, enum_type=None, containing_type=None, | ||
532 | is_extension=False, extension_scope=None, | ||
533 | options=None), | ||
534 | descriptor.FieldDescriptor( | ||
535 | name='output_type', full_name='froofle.protobuf.MethodDescriptorProto.output_type', index=2, | ||
536 | number=3, type=9, cpp_type=9, label=1, | ||
537 | default_value=unicode("", "utf-8"), | ||
538 | message_type=None, enum_type=None, containing_type=None, | ||
539 | is_extension=False, extension_scope=None, | ||
540 | options=None), | ||
541 | descriptor.FieldDescriptor( | ||
542 | name='options', full_name='froofle.protobuf.MethodDescriptorProto.options', index=3, | ||
543 | number=4, type=11, cpp_type=10, label=1, | ||
544 | default_value=None, | ||
545 | message_type=None, enum_type=None, containing_type=None, | ||
546 | is_extension=False, extension_scope=None, | ||
547 | options=None), | ||
548 | ], | ||
549 | extensions=[ | ||
550 | ], | ||
551 | nested_types=[], # TODO(robinson): Implement. | ||
552 | enum_types=[ | ||
553 | ], | ||
554 | options=None) | ||
555 | |||
556 | |||
557 | _FILEOPTIONS = descriptor.Descriptor( | ||
558 | name='FileOptions', | ||
559 | full_name='froofle.protobuf.FileOptions', | ||
560 | filename='froofle/protobuf/descriptor.proto', | ||
561 | containing_type=None, | ||
562 | fields=[ | ||
563 | descriptor.FieldDescriptor( | ||
564 | name='java_package', full_name='froofle.protobuf.FileOptions.java_package', index=0, | ||
565 | number=1, type=9, cpp_type=9, label=1, | ||
566 | default_value=unicode("", "utf-8"), | ||
567 | message_type=None, enum_type=None, containing_type=None, | ||
568 | is_extension=False, extension_scope=None, | ||
569 | options=None), | ||
570 | descriptor.FieldDescriptor( | ||
571 | name='java_outer_classname', full_name='froofle.protobuf.FileOptions.java_outer_classname', index=1, | ||
572 | number=8, type=9, cpp_type=9, label=1, | ||
573 | default_value=unicode("", "utf-8"), | ||
574 | message_type=None, enum_type=None, containing_type=None, | ||
575 | is_extension=False, extension_scope=None, | ||
576 | options=None), | ||
577 | descriptor.FieldDescriptor( | ||
578 | name='java_multiple_files', full_name='froofle.protobuf.FileOptions.java_multiple_files', index=2, | ||
579 | number=10, type=8, cpp_type=7, label=1, | ||
580 | default_value=False, | ||
581 | message_type=None, enum_type=None, containing_type=None, | ||
582 | is_extension=False, extension_scope=None, | ||
583 | options=None), | ||
584 | descriptor.FieldDescriptor( | ||
585 | name='optimize_for', full_name='froofle.protobuf.FileOptions.optimize_for', index=3, | ||
586 | number=9, type=14, cpp_type=8, label=1, | ||
587 | default_value=2, | ||
588 | message_type=None, enum_type=None, containing_type=None, | ||
589 | is_extension=False, extension_scope=None, | ||
590 | options=None), | ||
591 | descriptor.FieldDescriptor( | ||
592 | name='uninterpreted_option', full_name='froofle.protobuf.FileOptions.uninterpreted_option', index=4, | ||
593 | number=999, type=11, cpp_type=10, label=3, | ||
594 | default_value=[], | ||
595 | message_type=None, enum_type=None, containing_type=None, | ||
596 | is_extension=False, extension_scope=None, | ||
597 | options=None), | ||
598 | ], | ||
599 | extensions=[ | ||
600 | ], | ||
601 | nested_types=[], # TODO(robinson): Implement. | ||
602 | enum_types=[ | ||
603 | _FILEOPTIONS_OPTIMIZEMODE, | ||
604 | ], | ||
605 | options=None) | ||
606 | |||
607 | |||
608 | _MESSAGEOPTIONS = descriptor.Descriptor( | ||
609 | name='MessageOptions', | ||
610 | full_name='froofle.protobuf.MessageOptions', | ||
611 | filename='froofle/protobuf/descriptor.proto', | ||
612 | containing_type=None, | ||
613 | fields=[ | ||
614 | descriptor.FieldDescriptor( | ||
615 | name='message_set_wire_format', full_name='froofle.protobuf.MessageOptions.message_set_wire_format', index=0, | ||
616 | number=1, type=8, cpp_type=7, label=1, | ||
617 | default_value=False, | ||
618 | message_type=None, enum_type=None, containing_type=None, | ||
619 | is_extension=False, extension_scope=None, | ||
620 | options=None), | ||
621 | descriptor.FieldDescriptor( | ||
622 | name='uninterpreted_option', full_name='froofle.protobuf.MessageOptions.uninterpreted_option', index=1, | ||
623 | number=999, type=11, cpp_type=10, label=3, | ||
624 | default_value=[], | ||
625 | message_type=None, enum_type=None, containing_type=None, | ||
626 | is_extension=False, extension_scope=None, | ||
627 | options=None), | ||
628 | ], | ||
629 | extensions=[ | ||
630 | ], | ||
631 | nested_types=[], # TODO(robinson): Implement. | ||
632 | enum_types=[ | ||
633 | ], | ||
634 | options=None) | ||
635 | |||
636 | |||
637 | _FIELDOPTIONS = descriptor.Descriptor( | ||
638 | name='FieldOptions', | ||
639 | full_name='froofle.protobuf.FieldOptions', | ||
640 | filename='froofle/protobuf/descriptor.proto', | ||
641 | containing_type=None, | ||
642 | fields=[ | ||
643 | descriptor.FieldDescriptor( | ||
644 | name='ctype', full_name='froofle.protobuf.FieldOptions.ctype', index=0, | ||
645 | number=1, type=14, cpp_type=8, label=1, | ||
646 | default_value=1, | ||
647 | message_type=None, enum_type=None, containing_type=None, | ||
648 | is_extension=False, extension_scope=None, | ||
649 | options=None), | ||
650 | descriptor.FieldDescriptor( | ||
651 | name='experimental_map_key', full_name='froofle.protobuf.FieldOptions.experimental_map_key', index=1, | ||
652 | number=9, type=9, cpp_type=9, label=1, | ||
653 | default_value=unicode("", "utf-8"), | ||
654 | message_type=None, enum_type=None, containing_type=None, | ||
655 | is_extension=False, extension_scope=None, | ||
656 | options=None), | ||
657 | descriptor.FieldDescriptor( | ||
658 | name='uninterpreted_option', full_name='froofle.protobuf.FieldOptions.uninterpreted_option', index=2, | ||
659 | number=999, type=11, cpp_type=10, label=3, | ||
660 | default_value=[], | ||
661 | message_type=None, enum_type=None, containing_type=None, | ||
662 | is_extension=False, extension_scope=None, | ||
663 | options=None), | ||
664 | ], | ||
665 | extensions=[ | ||
666 | ], | ||
667 | nested_types=[], # TODO(robinson): Implement. | ||
668 | enum_types=[ | ||
669 | _FIELDOPTIONS_CTYPE, | ||
670 | ], | ||
671 | options=None) | ||
672 | |||
673 | |||
674 | _ENUMOPTIONS = descriptor.Descriptor( | ||
675 | name='EnumOptions', | ||
676 | full_name='froofle.protobuf.EnumOptions', | ||
677 | filename='froofle/protobuf/descriptor.proto', | ||
678 | containing_type=None, | ||
679 | fields=[ | ||
680 | descriptor.FieldDescriptor( | ||
681 | name='uninterpreted_option', full_name='froofle.protobuf.EnumOptions.uninterpreted_option', index=0, | ||
682 | number=999, type=11, cpp_type=10, label=3, | ||
683 | default_value=[], | ||
684 | message_type=None, enum_type=None, containing_type=None, | ||
685 | is_extension=False, extension_scope=None, | ||
686 | options=None), | ||
687 | ], | ||
688 | extensions=[ | ||
689 | ], | ||
690 | nested_types=[], # TODO(robinson): Implement. | ||
691 | enum_types=[ | ||
692 | ], | ||
693 | options=None) | ||
694 | |||
695 | |||
696 | _ENUMVALUEOPTIONS = descriptor.Descriptor( | ||
697 | name='EnumValueOptions', | ||
698 | full_name='froofle.protobuf.EnumValueOptions', | ||
699 | filename='froofle/protobuf/descriptor.proto', | ||
700 | containing_type=None, | ||
701 | fields=[ | ||
702 | descriptor.FieldDescriptor( | ||
703 | name='uninterpreted_option', full_name='froofle.protobuf.EnumValueOptions.uninterpreted_option', index=0, | ||
704 | number=999, type=11, cpp_type=10, label=3, | ||
705 | default_value=[], | ||
706 | message_type=None, enum_type=None, containing_type=None, | ||
707 | is_extension=False, extension_scope=None, | ||
708 | options=None), | ||
709 | ], | ||
710 | extensions=[ | ||
711 | ], | ||
712 | nested_types=[], # TODO(robinson): Implement. | ||
713 | enum_types=[ | ||
714 | ], | ||
715 | options=None) | ||
716 | |||
717 | |||
718 | _SERVICEOPTIONS = descriptor.Descriptor( | ||
719 | name='ServiceOptions', | ||
720 | full_name='froofle.protobuf.ServiceOptions', | ||
721 | filename='froofle/protobuf/descriptor.proto', | ||
722 | containing_type=None, | ||
723 | fields=[ | ||
724 | descriptor.FieldDescriptor( | ||
725 | name='uninterpreted_option', full_name='froofle.protobuf.ServiceOptions.uninterpreted_option', index=0, | ||
726 | number=999, type=11, cpp_type=10, label=3, | ||
727 | default_value=[], | ||
728 | message_type=None, enum_type=None, containing_type=None, | ||
729 | is_extension=False, extension_scope=None, | ||
730 | options=None), | ||
731 | ], | ||
732 | extensions=[ | ||
733 | ], | ||
734 | nested_types=[], # TODO(robinson): Implement. | ||
735 | enum_types=[ | ||
736 | ], | ||
737 | options=None) | ||
738 | |||
739 | |||
740 | _METHODOPTIONS = descriptor.Descriptor( | ||
741 | name='MethodOptions', | ||
742 | full_name='froofle.protobuf.MethodOptions', | ||
743 | filename='froofle/protobuf/descriptor.proto', | ||
744 | containing_type=None, | ||
745 | fields=[ | ||
746 | descriptor.FieldDescriptor( | ||
747 | name='uninterpreted_option', full_name='froofle.protobuf.MethodOptions.uninterpreted_option', index=0, | ||
748 | number=999, type=11, cpp_type=10, label=3, | ||
749 | default_value=[], | ||
750 | message_type=None, enum_type=None, containing_type=None, | ||
751 | is_extension=False, extension_scope=None, | ||
752 | options=None), | ||
753 | ], | ||
754 | extensions=[ | ||
755 | ], | ||
756 | nested_types=[], # TODO(robinson): Implement. | ||
757 | enum_types=[ | ||
758 | ], | ||
759 | options=None) | ||
760 | |||
761 | |||
762 | _UNINTERPRETEDOPTION_NAMEPART = descriptor.Descriptor( | ||
763 | name='NamePart', | ||
764 | full_name='froofle.protobuf.UninterpretedOption.NamePart', | ||
765 | filename='froofle/protobuf/descriptor.proto', | ||
766 | containing_type=None, | ||
767 | fields=[ | ||
768 | descriptor.FieldDescriptor( | ||
769 | name='name_part', full_name='froofle.protobuf.UninterpretedOption.NamePart.name_part', index=0, | ||
770 | number=1, type=9, cpp_type=9, label=2, | ||
771 | default_value=unicode("", "utf-8"), | ||
772 | message_type=None, enum_type=None, containing_type=None, | ||
773 | is_extension=False, extension_scope=None, | ||
774 | options=None), | ||
775 | descriptor.FieldDescriptor( | ||
776 | name='is_extension', full_name='froofle.protobuf.UninterpretedOption.NamePart.is_extension', index=1, | ||
777 | number=2, type=8, cpp_type=7, label=2, | ||
778 | default_value=False, | ||
779 | message_type=None, enum_type=None, containing_type=None, | ||
780 | is_extension=False, extension_scope=None, | ||
781 | options=None), | ||
782 | ], | ||
783 | extensions=[ | ||
784 | ], | ||
785 | nested_types=[], # TODO(robinson): Implement. | ||
786 | enum_types=[ | ||
787 | ], | ||
788 | options=None) | ||
789 | |||
790 | _UNINTERPRETEDOPTION = descriptor.Descriptor( | ||
791 | name='UninterpretedOption', | ||
792 | full_name='froofle.protobuf.UninterpretedOption', | ||
793 | filename='froofle/protobuf/descriptor.proto', | ||
794 | containing_type=None, | ||
795 | fields=[ | ||
796 | descriptor.FieldDescriptor( | ||
797 | name='name', full_name='froofle.protobuf.UninterpretedOption.name', index=0, | ||
798 | number=2, type=11, cpp_type=10, label=3, | ||
799 | default_value=[], | ||
800 | message_type=None, enum_type=None, containing_type=None, | ||
801 | is_extension=False, extension_scope=None, | ||
802 | options=None), | ||
803 | descriptor.FieldDescriptor( | ||
804 | name='identifier_value', full_name='froofle.protobuf.UninterpretedOption.identifier_value', index=1, | ||
805 | number=3, type=9, cpp_type=9, label=1, | ||
806 | default_value=unicode("", "utf-8"), | ||
807 | message_type=None, enum_type=None, containing_type=None, | ||
808 | is_extension=False, extension_scope=None, | ||
809 | options=None), | ||
810 | descriptor.FieldDescriptor( | ||
811 | name='positive_int_value', full_name='froofle.protobuf.UninterpretedOption.positive_int_value', index=2, | ||
812 | number=4, type=4, cpp_type=4, label=1, | ||
813 | default_value=0, | ||
814 | message_type=None, enum_type=None, containing_type=None, | ||
815 | is_extension=False, extension_scope=None, | ||
816 | options=None), | ||
817 | descriptor.FieldDescriptor( | ||
818 | name='negative_int_value', full_name='froofle.protobuf.UninterpretedOption.negative_int_value', index=3, | ||
819 | number=5, type=3, cpp_type=2, label=1, | ||
820 | default_value=0, | ||
821 | message_type=None, enum_type=None, containing_type=None, | ||
822 | is_extension=False, extension_scope=None, | ||
823 | options=None), | ||
824 | descriptor.FieldDescriptor( | ||
825 | name='double_value', full_name='froofle.protobuf.UninterpretedOption.double_value', index=4, | ||
826 | number=6, type=1, cpp_type=5, label=1, | ||
827 | default_value=0, | ||
828 | message_type=None, enum_type=None, containing_type=None, | ||
829 | is_extension=False, extension_scope=None, | ||
830 | options=None), | ||
831 | descriptor.FieldDescriptor( | ||
832 | name='string_value', full_name='froofle.protobuf.UninterpretedOption.string_value', index=5, | ||
833 | number=7, type=12, cpp_type=9, label=1, | ||
834 | default_value="", | ||
835 | message_type=None, enum_type=None, containing_type=None, | ||
836 | is_extension=False, extension_scope=None, | ||
837 | options=None), | ||
838 | ], | ||
839 | extensions=[ | ||
840 | ], | ||
841 | nested_types=[], # TODO(robinson): Implement. | ||
842 | enum_types=[ | ||
843 | ], | ||
844 | options=None) | ||
845 | |||
846 | |||
847 | _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO | ||
848 | _FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO | ||
849 | _FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO | ||
850 | _FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO | ||
851 | _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO | ||
852 | _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS | ||
853 | _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO | ||
854 | _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO | ||
855 | _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO | ||
856 | _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO | ||
857 | _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE | ||
858 | _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS | ||
859 | _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL | ||
860 | _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE | ||
861 | _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS | ||
862 | _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO | ||
863 | _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS | ||
864 | _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS | ||
865 | _SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO | ||
866 | _SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS | ||
867 | _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS | ||
868 | _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE | ||
869 | _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
870 | _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
871 | _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE | ||
872 | _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
873 | _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
874 | _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
875 | _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
876 | _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION | ||
877 | _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART | ||
878 | |||
879 | class FileDescriptorSet(message.Message): | ||
880 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
881 | DESCRIPTOR = _FILEDESCRIPTORSET | ||
882 | |||
883 | class FileDescriptorProto(message.Message): | ||
884 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
885 | DESCRIPTOR = _FILEDESCRIPTORPROTO | ||
886 | |||
887 | class DescriptorProto(message.Message): | ||
888 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
889 | |||
890 | class ExtensionRange(message.Message): | ||
891 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
892 | DESCRIPTOR = _DESCRIPTORPROTO_EXTENSIONRANGE | ||
893 | DESCRIPTOR = _DESCRIPTORPROTO | ||
894 | |||
895 | class FieldDescriptorProto(message.Message): | ||
896 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
897 | DESCRIPTOR = _FIELDDESCRIPTORPROTO | ||
898 | |||
899 | class EnumDescriptorProto(message.Message): | ||
900 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
901 | DESCRIPTOR = _ENUMDESCRIPTORPROTO | ||
902 | |||
903 | class EnumValueDescriptorProto(message.Message): | ||
904 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
905 | DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO | ||
906 | |||
907 | class ServiceDescriptorProto(message.Message): | ||
908 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
909 | DESCRIPTOR = _SERVICEDESCRIPTORPROTO | ||
910 | |||
911 | class MethodDescriptorProto(message.Message): | ||
912 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
913 | DESCRIPTOR = _METHODDESCRIPTORPROTO | ||
914 | |||
915 | class FileOptions(message.Message): | ||
916 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
917 | DESCRIPTOR = _FILEOPTIONS | ||
918 | |||
919 | class MessageOptions(message.Message): | ||
920 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
921 | DESCRIPTOR = _MESSAGEOPTIONS | ||
922 | |||
923 | class FieldOptions(message.Message): | ||
924 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
925 | DESCRIPTOR = _FIELDOPTIONS | ||
926 | |||
927 | class EnumOptions(message.Message): | ||
928 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
929 | DESCRIPTOR = _ENUMOPTIONS | ||
930 | |||
931 | class EnumValueOptions(message.Message): | ||
932 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
933 | DESCRIPTOR = _ENUMVALUEOPTIONS | ||
934 | |||
935 | class ServiceOptions(message.Message): | ||
936 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
937 | DESCRIPTOR = _SERVICEOPTIONS | ||
938 | |||
939 | class MethodOptions(message.Message): | ||
940 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
941 | DESCRIPTOR = _METHODOPTIONS | ||
942 | |||
943 | class UninterpretedOption(message.Message): | ||
944 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
945 | |||
946 | class NamePart(message.Message): | ||
947 | __metaclass__ = reflection.GeneratedProtocolMessageType | ||
948 | DESCRIPTOR = _UNINTERPRETEDOPTION_NAMEPART | ||
949 | DESCRIPTOR = _UNINTERPRETEDOPTION | ||
950 | |||
diff --git a/froofle/protobuf/internal/__init__.py b/froofle/protobuf/internal/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/froofle/protobuf/internal/__init__.py +++ /dev/null | |||
diff --git a/froofle/protobuf/internal/decoder.py b/froofle/protobuf/internal/decoder.py deleted file mode 100644 index 2dd4c96e..00000000 --- a/froofle/protobuf/internal/decoder.py +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Class for decoding protocol buffer primitives. | ||
32 | |||
33 | Contains the logic for decoding every logical protocol field type | ||
34 | from one of the 5 physical wire types. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from froofle.protobuf import message | ||
41 | from froofle.protobuf.internal import input_stream | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | |||
46 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
47 | # that the interface is strongly inspired by WireFormat from the C++ proto2 | ||
48 | # implementation. | ||
49 | |||
50 | |||
51 | class Decoder(object): | ||
52 | |||
53 | """Decodes logical protocol buffer fields from the wire.""" | ||
54 | |||
55 | def __init__(self, s): | ||
56 | """Initializes the decoder to read from s. | ||
57 | |||
58 | Args: | ||
59 | s: An immutable sequence of bytes, which must be accessible | ||
60 | via the Python buffer() primitive (i.e., buffer(s)). | ||
61 | """ | ||
62 | self._stream = input_stream.InputStream(s) | ||
63 | |||
64 | def EndOfStream(self): | ||
65 | """Returns true iff we've reached the end of the bytes we're reading.""" | ||
66 | return self._stream.EndOfStream() | ||
67 | |||
68 | def Position(self): | ||
69 | """Returns the 0-indexed position in |s|.""" | ||
70 | return self._stream.Position() | ||
71 | |||
72 | def ReadFieldNumberAndWireType(self): | ||
73 | """Reads a tag from the wire. Returns a (field_number, wire_type) pair.""" | ||
74 | tag_and_type = self.ReadUInt32() | ||
75 | return wire_format.UnpackTag(tag_and_type) | ||
76 | |||
77 | def SkipBytes(self, bytes): | ||
78 | """Skips the specified number of bytes on the wire.""" | ||
79 | self._stream.SkipBytes(bytes) | ||
80 | |||
81 | # Note that the Read*() methods below are not exactly symmetrical with the | ||
82 | # corresponding Encoder.Append*() methods. Those Encoder methods first | ||
83 | # encode a tag, but the Read*() methods below assume that the tag has already | ||
84 | # been read, and that the client wishes to read a field of the specified type | ||
85 | # starting at the current position. | ||
86 | |||
87 | def ReadInt32(self): | ||
88 | """Reads and returns a signed, varint-encoded, 32-bit integer.""" | ||
89 | return self._stream.ReadVarint32() | ||
90 | |||
91 | def ReadInt64(self): | ||
92 | """Reads and returns a signed, varint-encoded, 64-bit integer.""" | ||
93 | return self._stream.ReadVarint64() | ||
94 | |||
95 | def ReadUInt32(self): | ||
96 | """Reads and returns an signed, varint-encoded, 32-bit integer.""" | ||
97 | return self._stream.ReadVarUInt32() | ||
98 | |||
99 | def ReadUInt64(self): | ||
100 | """Reads and returns an signed, varint-encoded,64-bit integer.""" | ||
101 | return self._stream.ReadVarUInt64() | ||
102 | |||
103 | def ReadSInt32(self): | ||
104 | """Reads and returns a signed, zigzag-encoded, varint-encoded, | ||
105 | 32-bit integer.""" | ||
106 | return wire_format.ZigZagDecode(self._stream.ReadVarUInt32()) | ||
107 | |||
108 | def ReadSInt64(self): | ||
109 | """Reads and returns a signed, zigzag-encoded, varint-encoded, | ||
110 | 64-bit integer.""" | ||
111 | return wire_format.ZigZagDecode(self._stream.ReadVarUInt64()) | ||
112 | |||
113 | def ReadFixed32(self): | ||
114 | """Reads and returns an unsigned, fixed-width, 32-bit integer.""" | ||
115 | return self._stream.ReadLittleEndian32() | ||
116 | |||
117 | def ReadFixed64(self): | ||
118 | """Reads and returns an unsigned, fixed-width, 64-bit integer.""" | ||
119 | return self._stream.ReadLittleEndian64() | ||
120 | |||
121 | def ReadSFixed32(self): | ||
122 | """Reads and returns a signed, fixed-width, 32-bit integer.""" | ||
123 | value = self._stream.ReadLittleEndian32() | ||
124 | if value >= (1 << 31): | ||
125 | value -= (1 << 32) | ||
126 | return value | ||
127 | |||
128 | def ReadSFixed64(self): | ||
129 | """Reads and returns a signed, fixed-width, 64-bit integer.""" | ||
130 | value = self._stream.ReadLittleEndian64() | ||
131 | if value >= (1 << 63): | ||
132 | value -= (1 << 64) | ||
133 | return value | ||
134 | |||
135 | def ReadFloat(self): | ||
136 | """Reads and returns a 4-byte floating-point number.""" | ||
137 | serialized = self._stream.ReadBytes(4) | ||
138 | return struct.unpack('f', serialized)[0] | ||
139 | |||
140 | def ReadDouble(self): | ||
141 | """Reads and returns an 8-byte floating-point number.""" | ||
142 | serialized = self._stream.ReadBytes(8) | ||
143 | return struct.unpack('d', serialized)[0] | ||
144 | |||
145 | def ReadBool(self): | ||
146 | """Reads and returns a bool.""" | ||
147 | i = self._stream.ReadVarUInt32() | ||
148 | return bool(i) | ||
149 | |||
150 | def ReadEnum(self): | ||
151 | """Reads and returns an enum value.""" | ||
152 | return self._stream.ReadVarUInt32() | ||
153 | |||
154 | def ReadString(self): | ||
155 | """Reads and returns a length-delimited string.""" | ||
156 | bytes = self.ReadBytes() | ||
157 | return unicode(bytes, 'utf-8') | ||
158 | |||
159 | def ReadBytes(self): | ||
160 | """Reads and returns a length-delimited byte sequence.""" | ||
161 | length = self._stream.ReadVarUInt32() | ||
162 | return self._stream.ReadBytes(length) | ||
163 | |||
164 | def ReadMessageInto(self, msg): | ||
165 | """Calls msg.MergeFromString() to merge | ||
166 | length-delimited serialized message data into |msg|. | ||
167 | |||
168 | REQUIRES: The decoder must be positioned at the serialized "length" | ||
169 | prefix to a length-delmiited serialized message. | ||
170 | |||
171 | POSTCONDITION: The decoder is positioned just after the | ||
172 | serialized message, and we have merged those serialized | ||
173 | contents into |msg|. | ||
174 | """ | ||
175 | length = self._stream.ReadVarUInt32() | ||
176 | sub_buffer = self._stream.GetSubBuffer(length) | ||
177 | num_bytes_used = msg.MergeFromString(sub_buffer) | ||
178 | if num_bytes_used != length: | ||
179 | raise message.DecodeError( | ||
180 | 'Submessage told to deserialize from %d-byte encoding, ' | ||
181 | 'but used only %d bytes' % (length, num_bytes_used)) | ||
182 | self._stream.SkipBytes(num_bytes_used) | ||
183 | |||
184 | def ReadGroupInto(self, expected_field_number, group): | ||
185 | """Calls group.MergeFromString() to merge | ||
186 | END_GROUP-delimited serialized message data into |group|. | ||
187 | We'll raise an exception if we don't find an END_GROUP | ||
188 | tag immediately after the serialized message contents. | ||
189 | |||
190 | REQUIRES: The decoder is positioned just after the START_GROUP | ||
191 | tag for this group. | ||
192 | |||
193 | POSTCONDITION: The decoder is positioned just after the | ||
194 | END_GROUP tag for this group, and we have merged | ||
195 | the contents of the group into |group|. | ||
196 | """ | ||
197 | sub_buffer = self._stream.GetSubBuffer() # No a priori length limit. | ||
198 | num_bytes_used = group.MergeFromString(sub_buffer) | ||
199 | if num_bytes_used < 0: | ||
200 | raise message.DecodeError('Group message reported negative bytes read.') | ||
201 | self._stream.SkipBytes(num_bytes_used) | ||
202 | field_number, field_type = self.ReadFieldNumberAndWireType() | ||
203 | if field_type != wire_format.WIRETYPE_END_GROUP: | ||
204 | raise message.DecodeError('Group message did not end with an END_GROUP.') | ||
205 | if field_number != expected_field_number: | ||
206 | raise message.DecodeError('END_GROUP tag had field ' | ||
207 | 'number %d, was expecting field number %d' % ( | ||
208 | field_number, expected_field_number)) | ||
209 | # We're now positioned just after the END_GROUP tag. Perfect. | ||
diff --git a/froofle/protobuf/internal/encoder.py b/froofle/protobuf/internal/encoder.py deleted file mode 100644 index 8b924b3e..00000000 --- a/froofle/protobuf/internal/encoder.py +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Class for encoding protocol message primitives. | ||
32 | |||
33 | Contains the logic for encoding every logical protocol field type | ||
34 | into one of the 5 physical wire types. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from froofle.protobuf import message | ||
41 | from froofle.protobuf.internal import wire_format | ||
42 | from froofle.protobuf.internal import output_stream | ||
43 | |||
44 | |||
45 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
46 | # that the interface is strongly inspired by WireFormat from the C++ proto2 | ||
47 | # implementation. | ||
48 | |||
49 | |||
50 | class Encoder(object): | ||
51 | |||
52 | """Encodes logical protocol buffer fields to the wire format.""" | ||
53 | |||
54 | def __init__(self): | ||
55 | self._stream = output_stream.OutputStream() | ||
56 | |||
57 | def ToString(self): | ||
58 | """Returns all values encoded in this object as a string.""" | ||
59 | return self._stream.ToString() | ||
60 | |||
61 | # All the Append*() methods below first append a tag+type pair to the buffer | ||
62 | # before appending the specified value. | ||
63 | |||
64 | def AppendInt32(self, field_number, value): | ||
65 | """Appends a 32-bit integer to our buffer, varint-encoded.""" | ||
66 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
67 | self._stream.AppendVarint32(value) | ||
68 | |||
69 | def AppendInt64(self, field_number, value): | ||
70 | """Appends a 64-bit integer to our buffer, varint-encoded.""" | ||
71 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
72 | self._stream.AppendVarint64(value) | ||
73 | |||
74 | def AppendUInt32(self, field_number, unsigned_value): | ||
75 | """Appends an unsigned 32-bit integer to our buffer, varint-encoded.""" | ||
76 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
77 | self._stream.AppendVarUInt32(unsigned_value) | ||
78 | |||
79 | def AppendUInt64(self, field_number, unsigned_value): | ||
80 | """Appends an unsigned 64-bit integer to our buffer, varint-encoded.""" | ||
81 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
82 | self._stream.AppendVarUInt64(unsigned_value) | ||
83 | |||
84 | def AppendSInt32(self, field_number, value): | ||
85 | """Appends a 32-bit integer to our buffer, zigzag-encoded and then | ||
86 | varint-encoded. | ||
87 | """ | ||
88 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
89 | zigzag_value = wire_format.ZigZagEncode(value) | ||
90 | self._stream.AppendVarUInt32(zigzag_value) | ||
91 | |||
92 | def AppendSInt64(self, field_number, value): | ||
93 | """Appends a 64-bit integer to our buffer, zigzag-encoded and then | ||
94 | varint-encoded. | ||
95 | """ | ||
96 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
97 | zigzag_value = wire_format.ZigZagEncode(value) | ||
98 | self._stream.AppendVarUInt64(zigzag_value) | ||
99 | |||
100 | def AppendFixed32(self, field_number, unsigned_value): | ||
101 | """Appends an unsigned 32-bit integer to our buffer, in little-endian | ||
102 | byte-order. | ||
103 | """ | ||
104 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
105 | self._stream.AppendLittleEndian32(unsigned_value) | ||
106 | |||
107 | def AppendFixed64(self, field_number, unsigned_value): | ||
108 | """Appends an unsigned 64-bit integer to our buffer, in little-endian | ||
109 | byte-order. | ||
110 | """ | ||
111 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
112 | self._stream.AppendLittleEndian64(unsigned_value) | ||
113 | |||
114 | def AppendSFixed32(self, field_number, value): | ||
115 | """Appends a signed 32-bit integer to our buffer, in little-endian | ||
116 | byte-order. | ||
117 | """ | ||
118 | sign = (value & 0x80000000) and -1 or 0 | ||
119 | if value >> 32 != sign: | ||
120 | raise message.EncodeError('SFixed32 out of range: %d' % value) | ||
121 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
122 | self._stream.AppendLittleEndian32(value & 0xffffffff) | ||
123 | |||
124 | def AppendSFixed64(self, field_number, value): | ||
125 | """Appends a signed 64-bit integer to our buffer, in little-endian | ||
126 | byte-order. | ||
127 | """ | ||
128 | sign = (value & 0x8000000000000000) and -1 or 0 | ||
129 | if value >> 64 != sign: | ||
130 | raise message.EncodeError('SFixed64 out of range: %d' % value) | ||
131 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
132 | self._stream.AppendLittleEndian64(value & 0xffffffffffffffff) | ||
133 | |||
134 | def AppendFloat(self, field_number, value): | ||
135 | """Appends a floating-point number to our buffer.""" | ||
136 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
137 | self._stream.AppendRawBytes(struct.pack('f', value)) | ||
138 | |||
139 | def AppendDouble(self, field_number, value): | ||
140 | """Appends a double-precision floating-point number to our buffer.""" | ||
141 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
142 | self._stream.AppendRawBytes(struct.pack('d', value)) | ||
143 | |||
144 | def AppendBool(self, field_number, value): | ||
145 | """Appends a boolean to our buffer.""" | ||
146 | self.AppendInt32(field_number, value) | ||
147 | |||
148 | def AppendEnum(self, field_number, value): | ||
149 | """Appends an enum value to our buffer.""" | ||
150 | self.AppendInt32(field_number, value) | ||
151 | |||
152 | def AppendString(self, field_number, value): | ||
153 | """Appends a length-prefixed unicode string, encoded as UTF-8 to our buffer, | ||
154 | with the length varint-encoded. | ||
155 | """ | ||
156 | self.AppendBytes(field_number, value.encode('utf-8')) | ||
157 | |||
158 | def AppendBytes(self, field_number, value): | ||
159 | """Appends a length-prefixed sequence of bytes to our buffer, with the | ||
160 | length varint-encoded. | ||
161 | """ | ||
162 | self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) | ||
163 | self._stream.AppendVarUInt32(len(value)) | ||
164 | self._stream.AppendRawBytes(value) | ||
165 | |||
166 | # TODO(robinson): For AppendGroup() and AppendMessage(), we'd really like to | ||
167 | # avoid the extra string copy here. We can do so if we widen the Message | ||
168 | # interface to be able to serialize to a stream in addition to a string. The | ||
169 | # challenge when thinking ahead to the Python/C API implementation of Message | ||
170 | # is finding a stream-like Python thing to which we can write raw bytes | ||
171 | # from C. I'm not sure such a thing exists(?). (array.array is pretty much | ||
172 | # what we want, but it's not directly exposed in the Python/C API). | ||
173 | |||
174 | def AppendGroup(self, field_number, group): | ||
175 | """Appends a group to our buffer. | ||
176 | """ | ||
177 | self._AppendTag(field_number, wire_format.WIRETYPE_START_GROUP) | ||
178 | self._stream.AppendRawBytes(group.SerializeToString()) | ||
179 | self._AppendTag(field_number, wire_format.WIRETYPE_END_GROUP) | ||
180 | |||
181 | def AppendMessage(self, field_number, msg): | ||
182 | """Appends a nested message to our buffer. | ||
183 | """ | ||
184 | self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) | ||
185 | self._stream.AppendVarUInt32(msg.ByteSize()) | ||
186 | self._stream.AppendRawBytes(msg.SerializeToString()) | ||
187 | |||
188 | def AppendMessageSetItem(self, field_number, msg): | ||
189 | """Appends an item using the message set wire format. | ||
190 | |||
191 | The message set message looks like this: | ||
192 | message MessageSet { | ||
193 | repeated group Item = 1 { | ||
194 | required int32 type_id = 2; | ||
195 | required string message = 3; | ||
196 | } | ||
197 | } | ||
198 | """ | ||
199 | self._AppendTag(1, wire_format.WIRETYPE_START_GROUP) | ||
200 | self.AppendInt32(2, field_number) | ||
201 | self.AppendMessage(3, msg) | ||
202 | self._AppendTag(1, wire_format.WIRETYPE_END_GROUP) | ||
203 | |||
204 | def _AppendTag(self, field_number, wire_type): | ||
205 | """Appends a tag containing field number and wire type information.""" | ||
206 | self._stream.AppendVarUInt32(wire_format.PackTag(field_number, wire_type)) | ||
diff --git a/froofle/protobuf/internal/input_stream.py b/froofle/protobuf/internal/input_stream.py deleted file mode 100644 index 26a26dcf..00000000 --- a/froofle/protobuf/internal/input_stream.py +++ /dev/null | |||
@@ -1,326 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """InputStream is the primitive interface for reading bits from the wire. | ||
32 | |||
33 | All protocol buffer deserialization can be expressed in terms of | ||
34 | the InputStream primitives provided here. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from array import array | ||
41 | from froofle.protobuf import message | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
46 | # that the interface is strongly inspired by CodedInputStream from the C++ | ||
47 | # proto2 implementation. | ||
48 | |||
49 | |||
50 | class InputStreamBuffer(object): | ||
51 | |||
52 | """Contains all logic for reading bits, and dealing with stream position. | ||
53 | |||
54 | If an InputStream method ever raises an exception, the stream is left | ||
55 | in an indeterminate state and is not safe for further use. | ||
56 | """ | ||
57 | |||
58 | def __init__(self, s): | ||
59 | # What we really want is something like array('B', s), where elements we | ||
60 | # read from the array are already given to us as one-byte integers. BUT | ||
61 | # using array() instead of buffer() would force full string copies to result | ||
62 | # from each GetSubBuffer() call. | ||
63 | # | ||
64 | # So, if the N serialized bytes of a single protocol buffer object are | ||
65 | # split evenly between 2 child messages, and so on recursively, using | ||
66 | # array('B', s) instead of buffer() would incur an additional N*logN bytes | ||
67 | # copied during deserialization. | ||
68 | # | ||
69 | # The higher constant overhead of having to ord() for every byte we read | ||
70 | # from the buffer in _ReadVarintHelper() could definitely lead to worse | ||
71 | # performance in many real-world scenarios, even if the asymptotic | ||
72 | # complexity is better. However, our real answer is that the mythical | ||
73 | # Python/C extension module output mode for the protocol compiler will | ||
74 | # be blazing-fast and will eliminate most use of this class anyway. | ||
75 | self._buffer = buffer(s) | ||
76 | self._pos = 0 | ||
77 | |||
78 | def EndOfStream(self): | ||
79 | """Returns true iff we're at the end of the stream. | ||
80 | If this returns true, then a call to any other InputStream method | ||
81 | will raise an exception. | ||
82 | """ | ||
83 | return self._pos >= len(self._buffer) | ||
84 | |||
85 | def Position(self): | ||
86 | """Returns the current position in the stream, or equivalently, the | ||
87 | number of bytes read so far. | ||
88 | """ | ||
89 | return self._pos | ||
90 | |||
91 | def GetSubBuffer(self, size=None): | ||
92 | """Returns a sequence-like object that represents a portion of our | ||
93 | underlying sequence. | ||
94 | |||
95 | Position 0 in the returned object corresponds to self.Position() | ||
96 | in this stream. | ||
97 | |||
98 | If size is specified, then the returned object ends after the | ||
99 | next "size" bytes in this stream. If size is not specified, | ||
100 | then the returned object ends at the end of this stream. | ||
101 | |||
102 | We guarantee that the returned object R supports the Python buffer | ||
103 | interface (and thus that the call buffer(R) will work). | ||
104 | |||
105 | Note that the returned buffer is read-only. | ||
106 | |||
107 | The intended use for this method is for nested-message and nested-group | ||
108 | deserialization, where we want to make a recursive MergeFromString() | ||
109 | call on the portion of the original sequence that contains the serialized | ||
110 | nested message. (And we'd like to do so without making unnecessary string | ||
111 | copies). | ||
112 | |||
113 | REQUIRES: size is nonnegative. | ||
114 | """ | ||
115 | # Note that buffer() doesn't perform any actual string copy. | ||
116 | if size is None: | ||
117 | return buffer(self._buffer, self._pos) | ||
118 | else: | ||
119 | if size < 0: | ||
120 | raise message.DecodeError('Negative size %d' % size) | ||
121 | return buffer(self._buffer, self._pos, size) | ||
122 | |||
123 | def SkipBytes(self, num_bytes): | ||
124 | """Skip num_bytes bytes ahead, or go to the end of the stream, whichever | ||
125 | comes first. | ||
126 | |||
127 | REQUIRES: num_bytes is nonnegative. | ||
128 | """ | ||
129 | if num_bytes < 0: | ||
130 | raise message.DecodeError('Negative num_bytes %d' % num_bytes) | ||
131 | self._pos += num_bytes | ||
132 | self._pos = min(self._pos, len(self._buffer)) | ||
133 | |||
134 | def ReadBytes(self, size): | ||
135 | """Reads up to 'size' bytes from the stream, stopping early | ||
136 | only if we reach the end of the stream. Returns the bytes read | ||
137 | as a string. | ||
138 | """ | ||
139 | if size < 0: | ||
140 | raise message.DecodeError('Negative size %d' % size) | ||
141 | s = (self._buffer[self._pos : self._pos + size]) | ||
142 | self._pos += len(s) # Only advance by the number of bytes actually read. | ||
143 | return s | ||
144 | |||
145 | def ReadLittleEndian32(self): | ||
146 | """Interprets the next 4 bytes of the stream as a little-endian | ||
147 | encoded, unsiged 32-bit integer, and returns that integer. | ||
148 | """ | ||
149 | try: | ||
150 | i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, | ||
151 | self._buffer[self._pos : self._pos + 4]) | ||
152 | self._pos += 4 | ||
153 | return i[0] # unpack() result is a 1-element tuple. | ||
154 | except struct.error, e: | ||
155 | raise message.DecodeError(e) | ||
156 | |||
157 | def ReadLittleEndian64(self): | ||
158 | """Interprets the next 8 bytes of the stream as a little-endian | ||
159 | encoded, unsiged 64-bit integer, and returns that integer. | ||
160 | """ | ||
161 | try: | ||
162 | i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, | ||
163 | self._buffer[self._pos : self._pos + 8]) | ||
164 | self._pos += 8 | ||
165 | return i[0] # unpack() result is a 1-element tuple. | ||
166 | except struct.error, e: | ||
167 | raise message.DecodeError(e) | ||
168 | |||
169 | def ReadVarint32(self): | ||
170 | """Reads a varint from the stream, interprets this varint | ||
171 | as a signed, 32-bit integer, and returns the integer. | ||
172 | """ | ||
173 | i = self.ReadVarint64() | ||
174 | if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: | ||
175 | raise message.DecodeError('Value out of range for int32: %d' % i) | ||
176 | return int(i) | ||
177 | |||
178 | def ReadVarUInt32(self): | ||
179 | """Reads a varint from the stream, interprets this varint | ||
180 | as an unsigned, 32-bit integer, and returns the integer. | ||
181 | """ | ||
182 | i = self.ReadVarUInt64() | ||
183 | if i > wire_format.UINT32_MAX: | ||
184 | raise message.DecodeError('Value out of range for uint32: %d' % i) | ||
185 | return i | ||
186 | |||
187 | def ReadVarint64(self): | ||
188 | """Reads a varint from the stream, interprets this varint | ||
189 | as a signed, 64-bit integer, and returns the integer. | ||
190 | """ | ||
191 | i = self.ReadVarUInt64() | ||
192 | if i > wire_format.INT64_MAX: | ||
193 | i -= (1 << 64) | ||
194 | return i | ||
195 | |||
196 | def ReadVarUInt64(self): | ||
197 | """Reads a varint from the stream, interprets this varint | ||
198 | as an unsigned, 64-bit integer, and returns the integer. | ||
199 | """ | ||
200 | i = self._ReadVarintHelper() | ||
201 | if not 0 <= i <= wire_format.UINT64_MAX: | ||
202 | raise message.DecodeError('Value out of range for uint64: %d' % i) | ||
203 | return i | ||
204 | |||
205 | def _ReadVarintHelper(self): | ||
206 | """Helper for the various varint-reading methods above. | ||
207 | Reads an unsigned, varint-encoded integer from the stream and | ||
208 | returns this integer. | ||
209 | |||
210 | Does no bounds checking except to ensure that we read at most as many bytes | ||
211 | as could possibly be present in a varint-encoded 64-bit number. | ||
212 | """ | ||
213 | result = 0 | ||
214 | shift = 0 | ||
215 | while 1: | ||
216 | if shift >= 64: | ||
217 | raise message.DecodeError('Too many bytes when decoding varint.') | ||
218 | try: | ||
219 | b = ord(self._buffer[self._pos]) | ||
220 | except IndexError: | ||
221 | raise message.DecodeError('Truncated varint.') | ||
222 | self._pos += 1 | ||
223 | result |= ((b & 0x7f) << shift) | ||
224 | shift += 7 | ||
225 | if not (b & 0x80): | ||
226 | return result | ||
227 | |||
228 | class InputStreamArray(object): | ||
229 | def __init__(self, s): | ||
230 | self._buffer = array('B', s) | ||
231 | self._pos = 0 | ||
232 | |||
233 | def EndOfStream(self): | ||
234 | return self._pos >= len(self._buffer) | ||
235 | |||
236 | def Position(self): | ||
237 | return self._pos | ||
238 | |||
239 | def GetSubBuffer(self, size=None): | ||
240 | if size is None: | ||
241 | return self._buffer[self._pos : ].tostring() | ||
242 | else: | ||
243 | if size < 0: | ||
244 | raise message.DecodeError('Negative size %d' % size) | ||
245 | return self._buffer[self._pos : self._pos + size].tostring() | ||
246 | |||
247 | def SkipBytes(self, num_bytes): | ||
248 | if num_bytes < 0: | ||
249 | raise message.DecodeError('Negative num_bytes %d' % num_bytes) | ||
250 | self._pos += num_bytes | ||
251 | self._pos = min(self._pos, len(self._buffer)) | ||
252 | |||
253 | def ReadBytes(self, size): | ||
254 | if size < 0: | ||
255 | raise message.DecodeError('Negative size %d' % size) | ||
256 | s = self._buffer[self._pos : self._pos + size].tostring() | ||
257 | self._pos += len(s) # Only advance by the number of bytes actually read. | ||
258 | return s | ||
259 | |||
260 | def ReadLittleEndian32(self): | ||
261 | try: | ||
262 | i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, | ||
263 | self._buffer[self._pos : self._pos + 4]) | ||
264 | self._pos += 4 | ||
265 | return i[0] # unpack() result is a 1-element tuple. | ||
266 | except struct.error, e: | ||
267 | raise message.DecodeError(e) | ||
268 | |||
269 | def ReadLittleEndian64(self): | ||
270 | try: | ||
271 | i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, | ||
272 | self._buffer[self._pos : self._pos + 8]) | ||
273 | self._pos += 8 | ||
274 | return i[0] # unpack() result is a 1-element tuple. | ||
275 | except struct.error, e: | ||
276 | raise message.DecodeError(e) | ||
277 | |||
278 | def ReadVarint32(self): | ||
279 | i = self.ReadVarint64() | ||
280 | if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: | ||
281 | raise message.DecodeError('Value out of range for int32: %d' % i) | ||
282 | return int(i) | ||
283 | |||
284 | def ReadVarUInt32(self): | ||
285 | i = self.ReadVarUInt64() | ||
286 | if i > wire_format.UINT32_MAX: | ||
287 | raise message.DecodeError('Value out of range for uint32: %d' % i) | ||
288 | return i | ||
289 | |||
290 | def ReadVarint64(self): | ||
291 | i = self.ReadVarUInt64() | ||
292 | if i > wire_format.INT64_MAX: | ||
293 | i -= (1 << 64) | ||
294 | return i | ||
295 | |||
296 | def ReadVarUInt64(self): | ||
297 | i = self._ReadVarintHelper() | ||
298 | if not 0 <= i <= wire_format.UINT64_MAX: | ||
299 | raise message.DecodeError('Value out of range for uint64: %d' % i) | ||
300 | return i | ||
301 | |||
302 | def _ReadVarintHelper(self): | ||
303 | result = 0 | ||
304 | shift = 0 | ||
305 | while 1: | ||
306 | if shift >= 64: | ||
307 | raise message.DecodeError('Too many bytes when decoding varint.') | ||
308 | try: | ||
309 | b = self._buffer[self._pos] | ||
310 | except IndexError: | ||
311 | raise message.DecodeError('Truncated varint.') | ||
312 | self._pos += 1 | ||
313 | result |= ((b & 0x7f) << shift) | ||
314 | shift += 7 | ||
315 | if not (b & 0x80): | ||
316 | return result | ||
317 | |||
318 | try: | ||
319 | buffer("") | ||
320 | InputStream = InputStreamBuffer | ||
321 | except NotImplementedError: | ||
322 | # Google App Engine: dev_appserver.py | ||
323 | InputStream = InputStreamArray | ||
324 | except RuntimeError: | ||
325 | # Google App Engine: production | ||
326 | InputStream = InputStreamArray | ||
diff --git a/froofle/protobuf/internal/message_listener.py b/froofle/protobuf/internal/message_listener.py deleted file mode 100644 index 43978952..00000000 --- a/froofle/protobuf/internal/message_listener.py +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Defines a listener interface for observing certain | ||
32 | state transitions on Message objects. | ||
33 | |||
34 | Also defines a null implementation of this interface. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | |||
40 | class MessageListener(object): | ||
41 | |||
42 | """Listens for transitions to nonempty and for invalidations of cached | ||
43 | byte sizes. Meant to be registered via Message._SetListener(). | ||
44 | """ | ||
45 | |||
46 | def TransitionToNonempty(self): | ||
47 | """Called the *first* time that this message becomes nonempty. | ||
48 | Implementations are free (but not required) to call this method multiple | ||
49 | times after the message has become nonempty. | ||
50 | """ | ||
51 | raise NotImplementedError | ||
52 | |||
53 | def ByteSizeDirty(self): | ||
54 | """Called *every* time the cached byte size value | ||
55 | for this object is invalidated (transitions from being | ||
56 | "clean" to "dirty"). | ||
57 | """ | ||
58 | raise NotImplementedError | ||
59 | |||
60 | |||
61 | class NullMessageListener(object): | ||
62 | |||
63 | """No-op MessageListener implementation.""" | ||
64 | |||
65 | def TransitionToNonempty(self): | ||
66 | pass | ||
67 | |||
68 | def ByteSizeDirty(self): | ||
69 | pass | ||
diff --git a/froofle/protobuf/internal/output_stream.py b/froofle/protobuf/internal/output_stream.py deleted file mode 100644 index f62cd1c4..00000000 --- a/froofle/protobuf/internal/output_stream.py +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """OutputStream is the primitive interface for sticking bits on the wire. | ||
32 | |||
33 | All protocol buffer serialization can be expressed in terms of | ||
34 | the OutputStream primitives provided here. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import array | ||
40 | import struct | ||
41 | from froofle.protobuf import message | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | |||
46 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
47 | # that the interface is strongly inspired by CodedOutputStream from the C++ | ||
48 | # proto2 implementation. | ||
49 | |||
50 | |||
51 | class OutputStream(object): | ||
52 | |||
53 | """Contains all logic for writing bits, and ToString() to get the result.""" | ||
54 | |||
55 | def __init__(self): | ||
56 | self._buffer = array.array('B') | ||
57 | |||
58 | def AppendRawBytes(self, raw_bytes): | ||
59 | """Appends raw_bytes to our internal buffer.""" | ||
60 | self._buffer.fromstring(raw_bytes) | ||
61 | |||
62 | def AppendLittleEndian32(self, unsigned_value): | ||
63 | """Appends an unsigned 32-bit integer to the internal buffer, | ||
64 | in little-endian byte order. | ||
65 | """ | ||
66 | if not 0 <= unsigned_value <= wire_format.UINT32_MAX: | ||
67 | raise message.EncodeError( | ||
68 | 'Unsigned 32-bit out of range: %d' % unsigned_value) | ||
69 | self._buffer.fromstring(struct.pack( | ||
70 | wire_format.FORMAT_UINT32_LITTLE_ENDIAN, unsigned_value)) | ||
71 | |||
72 | def AppendLittleEndian64(self, unsigned_value): | ||
73 | """Appends an unsigned 64-bit integer to the internal buffer, | ||
74 | in little-endian byte order. | ||
75 | """ | ||
76 | if not 0 <= unsigned_value <= wire_format.UINT64_MAX: | ||
77 | raise message.EncodeError( | ||
78 | 'Unsigned 64-bit out of range: %d' % unsigned_value) | ||
79 | self._buffer.fromstring(struct.pack( | ||
80 | wire_format.FORMAT_UINT64_LITTLE_ENDIAN, unsigned_value)) | ||
81 | |||
82 | def AppendVarint32(self, value): | ||
83 | """Appends a signed 32-bit integer to the internal buffer, | ||
84 | encoded as a varint. (Note that a negative varint32 will | ||
85 | always require 10 bytes of space.) | ||
86 | """ | ||
87 | if not wire_format.INT32_MIN <= value <= wire_format.INT32_MAX: | ||
88 | raise message.EncodeError('Value out of range: %d' % value) | ||
89 | self.AppendVarint64(value) | ||
90 | |||
91 | def AppendVarUInt32(self, value): | ||
92 | """Appends an unsigned 32-bit integer to the internal buffer, | ||
93 | encoded as a varint. | ||
94 | """ | ||
95 | if not 0 <= value <= wire_format.UINT32_MAX: | ||
96 | raise message.EncodeError('Value out of range: %d' % value) | ||
97 | self.AppendVarUInt64(value) | ||
98 | |||
99 | def AppendVarint64(self, value): | ||
100 | """Appends a signed 64-bit integer to the internal buffer, | ||
101 | encoded as a varint. | ||
102 | """ | ||
103 | if not wire_format.INT64_MIN <= value <= wire_format.INT64_MAX: | ||
104 | raise message.EncodeError('Value out of range: %d' % value) | ||
105 | if value < 0: | ||
106 | value += (1 << 64) | ||
107 | self.AppendVarUInt64(value) | ||
108 | |||
109 | def AppendVarUInt64(self, unsigned_value): | ||
110 | """Appends an unsigned 64-bit integer to the internal buffer, | ||
111 | encoded as a varint. | ||
112 | """ | ||
113 | if not 0 <= unsigned_value <= wire_format.UINT64_MAX: | ||
114 | raise message.EncodeError('Value out of range: %d' % unsigned_value) | ||
115 | while True: | ||
116 | bits = unsigned_value & 0x7f | ||
117 | unsigned_value >>= 7 | ||
118 | if not unsigned_value: | ||
119 | self._buffer.append(bits) | ||
120 | break | ||
121 | self._buffer.append(0x80|bits) | ||
122 | |||
123 | def ToString(self): | ||
124 | """Returns a string containing the bytes in our internal buffer.""" | ||
125 | return self._buffer.tostring() | ||
diff --git a/froofle/protobuf/internal/type_checkers.py b/froofle/protobuf/internal/type_checkers.py deleted file mode 100644 index aaf7a844..00000000 --- a/froofle/protobuf/internal/type_checkers.py +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Provides type checking routines. | ||
32 | |||
33 | This module defines type checking utilities in the forms of dictionaries: | ||
34 | |||
35 | VALUE_CHECKERS: A dictionary of field types and a value validation object. | ||
36 | TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing | ||
37 | function. | ||
38 | TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization | ||
39 | function. | ||
40 | FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their | ||
41 | coresponding wire types. | ||
42 | TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization | ||
43 | function. | ||
44 | """ | ||
45 | |||
46 | __author__ = 'robinson@google.com (Will Robinson)' | ||
47 | |||
48 | from froofle.protobuf.internal import decoder | ||
49 | from froofle.protobuf.internal import encoder | ||
50 | from froofle.protobuf.internal import wire_format | ||
51 | from froofle.protobuf import descriptor | ||
52 | |||
53 | _FieldDescriptor = descriptor.FieldDescriptor | ||
54 | |||
55 | |||
56 | def GetTypeChecker(cpp_type, field_type): | ||
57 | """Returns a type checker for a message field of the specified types. | ||
58 | |||
59 | Args: | ||
60 | cpp_type: C++ type of the field (see descriptor.py). | ||
61 | field_type: Protocol message field type (see descriptor.py). | ||
62 | |||
63 | Returns: | ||
64 | An instance of TypeChecker which can be used to verify the types | ||
65 | of values assigned to a field of the specified type. | ||
66 | """ | ||
67 | if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and | ||
68 | field_type == _FieldDescriptor.TYPE_STRING): | ||
69 | return UnicodeValueChecker() | ||
70 | return _VALUE_CHECKERS[cpp_type] | ||
71 | |||
72 | |||
73 | # None of the typecheckers below make any attempt to guard against people | ||
74 | # subclassing builtin types and doing weird things. We're not trying to | ||
75 | # protect against malicious clients here, just people accidentally shooting | ||
76 | # themselves in the foot in obvious ways. | ||
77 | |||
78 | class TypeChecker(object): | ||
79 | |||
80 | """Type checker used to catch type errors as early as possible | ||
81 | when the client is setting scalar fields in protocol messages. | ||
82 | """ | ||
83 | |||
84 | def __init__(self, *acceptable_types): | ||
85 | self._acceptable_types = acceptable_types | ||
86 | |||
87 | def CheckValue(self, proposed_value): | ||
88 | if not isinstance(proposed_value, self._acceptable_types): | ||
89 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
90 | (proposed_value, type(proposed_value), self._acceptable_types)) | ||
91 | raise TypeError(message) | ||
92 | |||
93 | |||
94 | # IntValueChecker and its subclasses perform integer type-checks | ||
95 | # and bounds-checks. | ||
96 | class IntValueChecker(object): | ||
97 | |||
98 | """Checker used for integer fields. Performs type-check and range check.""" | ||
99 | |||
100 | def CheckValue(self, proposed_value): | ||
101 | if not isinstance(proposed_value, (int, long)): | ||
102 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
103 | (proposed_value, type(proposed_value), (int, long))) | ||
104 | raise TypeError(message) | ||
105 | if not self._MIN <= proposed_value <= self._MAX: | ||
106 | raise ValueError('Value out of range: %d' % proposed_value) | ||
107 | |||
108 | |||
109 | class UnicodeValueChecker(object): | ||
110 | |||
111 | """Checker used for string fields.""" | ||
112 | |||
113 | def CheckValue(self, proposed_value): | ||
114 | if not isinstance(proposed_value, (str, unicode)): | ||
115 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
116 | (proposed_value, type(proposed_value), (str, unicode))) | ||
117 | raise TypeError(message) | ||
118 | |||
119 | # If the value is of type 'str' make sure that it is in 7-bit ASCII | ||
120 | # encoding. | ||
121 | if isinstance(proposed_value, str): | ||
122 | try: | ||
123 | unicode(proposed_value, 'ascii') | ||
124 | except UnicodeDecodeError: | ||
125 | raise ValueError('%.1024r isn\'t in 7-bit ASCII encoding.' | ||
126 | % (proposed_value)) | ||
127 | |||
128 | |||
129 | class Int32ValueChecker(IntValueChecker): | ||
130 | # We're sure to use ints instead of longs here since comparison may be more | ||
131 | # efficient. | ||
132 | _MIN = -2147483648 | ||
133 | _MAX = 2147483647 | ||
134 | |||
135 | |||
136 | class Uint32ValueChecker(IntValueChecker): | ||
137 | _MIN = 0 | ||
138 | _MAX = (1 << 32) - 1 | ||
139 | |||
140 | |||
141 | class Int64ValueChecker(IntValueChecker): | ||
142 | _MIN = -(1 << 63) | ||
143 | _MAX = (1 << 63) - 1 | ||
144 | |||
145 | |||
146 | class Uint64ValueChecker(IntValueChecker): | ||
147 | _MIN = 0 | ||
148 | _MAX = (1 << 64) - 1 | ||
149 | |||
150 | |||
151 | # Type-checkers for all scalar CPPTYPEs. | ||
152 | _VALUE_CHECKERS = { | ||
153 | _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), | ||
154 | _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), | ||
155 | _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), | ||
156 | _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), | ||
157 | _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker( | ||
158 | float, int, long), | ||
159 | _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( | ||
160 | float, int, long), | ||
161 | _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), | ||
162 | _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(), | ||
163 | _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str), | ||
164 | } | ||
165 | |||
166 | |||
167 | # Map from field type to a function F, such that F(field_num, value) | ||
168 | # gives the total byte size for a value of the given type. This | ||
169 | # byte size includes tag information and any other additional space | ||
170 | # associated with serializing "value". | ||
171 | TYPE_TO_BYTE_SIZE_FN = { | ||
172 | _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, | ||
173 | _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, | ||
174 | _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, | ||
175 | _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, | ||
176 | _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, | ||
177 | _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, | ||
178 | _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, | ||
179 | _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, | ||
180 | _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, | ||
181 | _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, | ||
182 | _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, | ||
183 | _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, | ||
184 | _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, | ||
185 | _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, | ||
186 | _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, | ||
187 | _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, | ||
188 | _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, | ||
189 | _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize | ||
190 | } | ||
191 | |||
192 | |||
193 | # Maps from field type to an unbound Encoder method F, such that | ||
194 | # F(encoder, field_number, value) will append the serialization | ||
195 | # of a value of this type to the encoder. | ||
196 | _Encoder = encoder.Encoder | ||
197 | TYPE_TO_SERIALIZE_METHOD = { | ||
198 | _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDouble, | ||
199 | _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloat, | ||
200 | _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64, | ||
201 | _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64, | ||
202 | _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32, | ||
203 | _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64, | ||
204 | _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32, | ||
205 | _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBool, | ||
206 | _FieldDescriptor.TYPE_STRING: _Encoder.AppendString, | ||
207 | _FieldDescriptor.TYPE_GROUP: _Encoder.AppendGroup, | ||
208 | _FieldDescriptor.TYPE_MESSAGE: _Encoder.AppendMessage, | ||
209 | _FieldDescriptor.TYPE_BYTES: _Encoder.AppendBytes, | ||
210 | _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32, | ||
211 | _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnum, | ||
212 | _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32, | ||
213 | _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64, | ||
214 | _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32, | ||
215 | _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64, | ||
216 | } | ||
217 | |||
218 | |||
219 | # Maps from field type to expected wiretype. | ||
220 | FIELD_TYPE_TO_WIRE_TYPE = { | ||
221 | _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, | ||
222 | _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, | ||
223 | _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, | ||
224 | _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, | ||
225 | _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, | ||
226 | _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, | ||
227 | _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, | ||
228 | _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, | ||
229 | _FieldDescriptor.TYPE_STRING: | ||
230 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
231 | _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, | ||
232 | _FieldDescriptor.TYPE_MESSAGE: | ||
233 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
234 | _FieldDescriptor.TYPE_BYTES: | ||
235 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
236 | _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, | ||
237 | _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, | ||
238 | _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, | ||
239 | _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, | ||
240 | _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, | ||
241 | _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, | ||
242 | } | ||
243 | |||
244 | |||
245 | # Maps from field type to an unbound Decoder method F, | ||
246 | # such that F(decoder) will read a field of the requested type. | ||
247 | # | ||
248 | # Note that Message and Group are intentionally missing here. | ||
249 | # They're handled by _RecursivelyMerge(). | ||
250 | _Decoder = decoder.Decoder | ||
251 | TYPE_TO_DESERIALIZE_METHOD = { | ||
252 | _FieldDescriptor.TYPE_DOUBLE: _Decoder.ReadDouble, | ||
253 | _FieldDescriptor.TYPE_FLOAT: _Decoder.ReadFloat, | ||
254 | _FieldDescriptor.TYPE_INT64: _Decoder.ReadInt64, | ||
255 | _FieldDescriptor.TYPE_UINT64: _Decoder.ReadUInt64, | ||
256 | _FieldDescriptor.TYPE_INT32: _Decoder.ReadInt32, | ||
257 | _FieldDescriptor.TYPE_FIXED64: _Decoder.ReadFixed64, | ||
258 | _FieldDescriptor.TYPE_FIXED32: _Decoder.ReadFixed32, | ||
259 | _FieldDescriptor.TYPE_BOOL: _Decoder.ReadBool, | ||
260 | _FieldDescriptor.TYPE_STRING: _Decoder.ReadString, | ||
261 | _FieldDescriptor.TYPE_BYTES: _Decoder.ReadBytes, | ||
262 | _FieldDescriptor.TYPE_UINT32: _Decoder.ReadUInt32, | ||
263 | _FieldDescriptor.TYPE_ENUM: _Decoder.ReadEnum, | ||
264 | _FieldDescriptor.TYPE_SFIXED32: _Decoder.ReadSFixed32, | ||
265 | _FieldDescriptor.TYPE_SFIXED64: _Decoder.ReadSFixed64, | ||
266 | _FieldDescriptor.TYPE_SINT32: _Decoder.ReadSInt32, | ||
267 | _FieldDescriptor.TYPE_SINT64: _Decoder.ReadSInt64, | ||
268 | } | ||
diff --git a/froofle/protobuf/internal/wire_format.py b/froofle/protobuf/internal/wire_format.py deleted file mode 100644 index 4d823c8d..00000000 --- a/froofle/protobuf/internal/wire_format.py +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Constants and static functions to support protocol buffer wire format.""" | ||
32 | |||
33 | __author__ = 'robinson@google.com (Will Robinson)' | ||
34 | |||
35 | import struct | ||
36 | from froofle.protobuf import message | ||
37 | |||
38 | |||
39 | TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. | ||
40 | _TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 | ||
41 | |||
42 | # These numbers identify the wire type of a protocol buffer value. | ||
43 | # We use the least-significant TAG_TYPE_BITS bits of the varint-encoded | ||
44 | # tag-and-type to store one of these WIRETYPE_* constants. | ||
45 | # These values must match WireType enum in //net/proto2/public/wire_format.h. | ||
46 | WIRETYPE_VARINT = 0 | ||
47 | WIRETYPE_FIXED64 = 1 | ||
48 | WIRETYPE_LENGTH_DELIMITED = 2 | ||
49 | WIRETYPE_START_GROUP = 3 | ||
50 | WIRETYPE_END_GROUP = 4 | ||
51 | WIRETYPE_FIXED32 = 5 | ||
52 | _WIRETYPE_MAX = 5 | ||
53 | |||
54 | |||
55 | # Bounds for various integer types. | ||
56 | INT32_MAX = int((1 << 31) - 1) | ||
57 | INT32_MIN = int(-(1 << 31)) | ||
58 | UINT32_MAX = (1 << 32) - 1 | ||
59 | |||
60 | INT64_MAX = (1 << 63) - 1 | ||
61 | INT64_MIN = -(1 << 63) | ||
62 | UINT64_MAX = (1 << 64) - 1 | ||
63 | |||
64 | # "struct" format strings that will encode/decode the specified formats. | ||
65 | FORMAT_UINT32_LITTLE_ENDIAN = '<I' | ||
66 | FORMAT_UINT64_LITTLE_ENDIAN = '<Q' | ||
67 | |||
68 | |||
69 | # We'll have to provide alternate implementations of AppendLittleEndian*() on | ||
70 | # any architectures where these checks fail. | ||
71 | if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4: | ||
72 | raise AssertionError('Format "I" is not a 32-bit number.') | ||
73 | if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8: | ||
74 | raise AssertionError('Format "Q" is not a 64-bit number.') | ||
75 | |||
76 | |||
77 | def PackTag(field_number, wire_type): | ||
78 | """Returns an unsigned 32-bit integer that encodes the field number and | ||
79 | wire type information in standard protocol message wire format. | ||
80 | |||
81 | Args: | ||
82 | field_number: Expected to be an integer in the range [1, 1 << 29) | ||
83 | wire_type: One of the WIRETYPE_* constants. | ||
84 | """ | ||
85 | if not 0 <= wire_type <= _WIRETYPE_MAX: | ||
86 | raise message.EncodeError('Unknown wire type: %d' % wire_type) | ||
87 | return (field_number << TAG_TYPE_BITS) | wire_type | ||
88 | |||
89 | |||
90 | def UnpackTag(tag): | ||
91 | """The inverse of PackTag(). Given an unsigned 32-bit number, | ||
92 | returns a (field_number, wire_type) tuple. | ||
93 | """ | ||
94 | return (tag >> TAG_TYPE_BITS), (tag & _TAG_TYPE_MASK) | ||
95 | |||
96 | |||
97 | def ZigZagEncode(value): | ||
98 | """ZigZag Transform: Encodes signed integers so that they can be | ||
99 | effectively used with varint encoding. See wire_format.h for | ||
100 | more details. | ||
101 | """ | ||
102 | if value >= 0: | ||
103 | return value << 1 | ||
104 | return (value << 1) ^ (~0) | ||
105 | |||
106 | |||
107 | def ZigZagDecode(value): | ||
108 | """Inverse of ZigZagEncode().""" | ||
109 | if not value & 0x1: | ||
110 | return value >> 1 | ||
111 | return (value >> 1) ^ (~0) | ||
112 | |||
113 | |||
114 | |||
115 | # The *ByteSize() functions below return the number of bytes required to | ||
116 | # serialize "field number + type" information and then serialize the value. | ||
117 | |||
118 | |||
119 | def Int32ByteSize(field_number, int32): | ||
120 | return Int64ByteSize(field_number, int32) | ||
121 | |||
122 | |||
123 | def Int64ByteSize(field_number, int64): | ||
124 | # Have to convert to uint before calling UInt64ByteSize(). | ||
125 | return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) | ||
126 | |||
127 | |||
128 | def UInt32ByteSize(field_number, uint32): | ||
129 | return UInt64ByteSize(field_number, uint32) | ||
130 | |||
131 | |||
132 | def UInt64ByteSize(field_number, uint64): | ||
133 | return _TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) | ||
134 | |||
135 | |||
136 | def SInt32ByteSize(field_number, int32): | ||
137 | return UInt32ByteSize(field_number, ZigZagEncode(int32)) | ||
138 | |||
139 | |||
140 | def SInt64ByteSize(field_number, int64): | ||
141 | return UInt64ByteSize(field_number, ZigZagEncode(int64)) | ||
142 | |||
143 | |||
144 | def Fixed32ByteSize(field_number, fixed32): | ||
145 | return _TagByteSize(field_number) + 4 | ||
146 | |||
147 | |||
148 | def Fixed64ByteSize(field_number, fixed64): | ||
149 | return _TagByteSize(field_number) + 8 | ||
150 | |||
151 | |||
152 | def SFixed32ByteSize(field_number, sfixed32): | ||
153 | return _TagByteSize(field_number) + 4 | ||
154 | |||
155 | |||
156 | def SFixed64ByteSize(field_number, sfixed64): | ||
157 | return _TagByteSize(field_number) + 8 | ||
158 | |||
159 | |||
160 | def FloatByteSize(field_number, flt): | ||
161 | return _TagByteSize(field_number) + 4 | ||
162 | |||
163 | |||
164 | def DoubleByteSize(field_number, double): | ||
165 | return _TagByteSize(field_number) + 8 | ||
166 | |||
167 | |||
168 | def BoolByteSize(field_number, b): | ||
169 | return _TagByteSize(field_number) + 1 | ||
170 | |||
171 | |||
172 | def EnumByteSize(field_number, enum): | ||
173 | return UInt32ByteSize(field_number, enum) | ||
174 | |||
175 | |||
176 | def StringByteSize(field_number, string): | ||
177 | return BytesByteSize(field_number, string.encode('utf-8')) | ||
178 | |||
179 | |||
180 | def BytesByteSize(field_number, b): | ||
181 | return (_TagByteSize(field_number) | ||
182 | + _VarUInt64ByteSizeNoTag(len(b)) | ||
183 | + len(b)) | ||
184 | |||
185 | |||
186 | def GroupByteSize(field_number, message): | ||
187 | return (2 * _TagByteSize(field_number) # START and END group. | ||
188 | + message.ByteSize()) | ||
189 | |||
190 | |||
191 | def MessageByteSize(field_number, message): | ||
192 | return (_TagByteSize(field_number) | ||
193 | + _VarUInt64ByteSizeNoTag(message.ByteSize()) | ||
194 | + message.ByteSize()) | ||
195 | |||
196 | |||
197 | def MessageSetItemByteSize(field_number, msg): | ||
198 | # First compute the sizes of the tags. | ||
199 | # There are 2 tags for the beginning and ending of the repeated group, that | ||
200 | # is field number 1, one with field number 2 (type_id) and one with field | ||
201 | # number 3 (message). | ||
202 | total_size = (2 * _TagByteSize(1) + _TagByteSize(2) + _TagByteSize(3)) | ||
203 | |||
204 | # Add the number of bytes for type_id. | ||
205 | total_size += _VarUInt64ByteSizeNoTag(field_number) | ||
206 | |||
207 | message_size = msg.ByteSize() | ||
208 | |||
209 | # The number of bytes for encoding the length of the message. | ||
210 | total_size += _VarUInt64ByteSizeNoTag(message_size) | ||
211 | |||
212 | # The size of the message. | ||
213 | total_size += message_size | ||
214 | return total_size | ||
215 | |||
216 | |||
217 | # Private helper functions for the *ByteSize() functions above. | ||
218 | |||
219 | |||
220 | def _TagByteSize(field_number): | ||
221 | """Returns the bytes required to serialize a tag with this field number.""" | ||
222 | # Just pass in type 0, since the type won't affect the tag+type size. | ||
223 | return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) | ||
224 | |||
225 | |||
226 | def _VarUInt64ByteSizeNoTag(uint64): | ||
227 | """Returns the bytes required to serialize a single varint. | ||
228 | uint64 must be unsigned. | ||
229 | """ | ||
230 | if uint64 > UINT64_MAX: | ||
231 | raise message.EncodeError('Value out of range: %d' % uint64) | ||
232 | bytes = 1 | ||
233 | while uint64 > 0x7f: | ||
234 | bytes += 1 | ||
235 | uint64 >>= 7 | ||
236 | return bytes | ||
diff --git a/froofle/protobuf/message.py b/froofle/protobuf/message.py deleted file mode 100644 index ed714853..00000000 --- a/froofle/protobuf/message.py +++ /dev/null | |||
@@ -1,246 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | # TODO(robinson): We should just make these methods all "pure-virtual" and move | ||
32 | # all implementation out, into reflection.py for now. | ||
33 | |||
34 | |||
35 | """Contains an abstract base class for protocol messages.""" | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | from froofle.protobuf import text_format | ||
40 | |||
41 | class Error(Exception): pass | ||
42 | class DecodeError(Error): pass | ||
43 | class EncodeError(Error): pass | ||
44 | |||
45 | |||
46 | class Message(object): | ||
47 | |||
48 | """Abstract base class for protocol messages. | ||
49 | |||
50 | Protocol message classes are almost always generated by the protocol | ||
51 | compiler. These generated types subclass Message and implement the methods | ||
52 | shown below. | ||
53 | |||
54 | TODO(robinson): Link to an HTML document here. | ||
55 | |||
56 | TODO(robinson): Document that instances of this class will also | ||
57 | have an Extensions attribute with __getitem__ and __setitem__. | ||
58 | Again, not sure how to best convey this. | ||
59 | |||
60 | TODO(robinson): Document that the class must also have a static | ||
61 | RegisterExtension(extension_field) method. | ||
62 | Not sure how to best express at this point. | ||
63 | """ | ||
64 | |||
65 | # TODO(robinson): Document these fields and methods. | ||
66 | |||
67 | __slots__ = [] | ||
68 | |||
69 | DESCRIPTOR = None | ||
70 | |||
71 | def __eq__(self, other_msg): | ||
72 | raise NotImplementedError | ||
73 | |||
74 | def __ne__(self, other_msg): | ||
75 | # Can't just say self != other_msg, since that would infinitely recurse. :) | ||
76 | return not self == other_msg | ||
77 | |||
78 | def __str__(self): | ||
79 | return text_format.MessageToString(self) | ||
80 | |||
81 | def MergeFrom(self, other_msg): | ||
82 | """Merges the contents of the specified message into current message. | ||
83 | |||
84 | This method merges the contents of the specified message into the current | ||
85 | message. Singular fields that are set in the specified message overwrite | ||
86 | the corresponding fields in the current message. Repeated fields are | ||
87 | appended. Singular sub-messages and groups are recursively merged. | ||
88 | |||
89 | Args: | ||
90 | other_msg: Message to merge into the current message. | ||
91 | """ | ||
92 | raise NotImplementedError | ||
93 | |||
94 | def CopyFrom(self, other_msg): | ||
95 | """Copies the content of the specified message into the current message. | ||
96 | |||
97 | The method clears the current message and then merges the specified | ||
98 | message using MergeFrom. | ||
99 | |||
100 | Args: | ||
101 | other_msg: Message to copy into the current one. | ||
102 | """ | ||
103 | if self == other_msg: | ||
104 | return | ||
105 | self.Clear() | ||
106 | self.MergeFrom(other_msg) | ||
107 | |||
108 | def Clear(self): | ||
109 | """Clears all data that was set in the message.""" | ||
110 | raise NotImplementedError | ||
111 | |||
112 | def IsInitialized(self): | ||
113 | """Checks if the message is initialized. | ||
114 | |||
115 | Returns: | ||
116 | The method returns True if the message is initialized (i.e. all of its | ||
117 | required fields are set). | ||
118 | """ | ||
119 | raise NotImplementedError | ||
120 | |||
121 | # TODO(robinson): MergeFromString() should probably return None and be | ||
122 | # implemented in terms of a helper that returns the # of bytes read. Our | ||
123 | # deserialization routines would use the helper when recursively | ||
124 | # deserializing, but the end user would almost always just want the no-return | ||
125 | # MergeFromString(). | ||
126 | |||
127 | def MergeFromString(self, serialized): | ||
128 | """Merges serialized protocol buffer data into this message. | ||
129 | |||
130 | When we find a field in |serialized| that is already present | ||
131 | in this message: | ||
132 | - If it's a "repeated" field, we append to the end of our list. | ||
133 | - Else, if it's a scalar, we overwrite our field. | ||
134 | - Else, (it's a nonrepeated composite), we recursively merge | ||
135 | into the existing composite. | ||
136 | |||
137 | TODO(robinson): Document handling of unknown fields. | ||
138 | |||
139 | Args: | ||
140 | serialized: Any object that allows us to call buffer(serialized) | ||
141 | to access a string of bytes using the buffer interface. | ||
142 | |||
143 | TODO(robinson): When we switch to a helper, this will return None. | ||
144 | |||
145 | Returns: | ||
146 | The number of bytes read from |serialized|. | ||
147 | For non-group messages, this will always be len(serialized), | ||
148 | but for messages which are actually groups, this will | ||
149 | generally be less than len(serialized), since we must | ||
150 | stop when we reach an END_GROUP tag. Note that if | ||
151 | we *do* stop because of an END_GROUP tag, the number | ||
152 | of bytes returned does not include the bytes | ||
153 | for the END_GROUP tag information. | ||
154 | """ | ||
155 | raise NotImplementedError | ||
156 | |||
157 | def ParseFromString(self, serialized): | ||
158 | """Like MergeFromString(), except we clear the object first.""" | ||
159 | self.Clear() | ||
160 | self.MergeFromString(serialized) | ||
161 | |||
162 | def SerializeToString(self): | ||
163 | """Serializes the protocol message to a binary string. | ||
164 | |||
165 | Returns: | ||
166 | A binary string representation of the message if all of the required | ||
167 | fields in the message are set (i.e. the message is initialized). | ||
168 | |||
169 | Raises: | ||
170 | message.EncodeError if the message isn't initialized. | ||
171 | """ | ||
172 | raise NotImplementedError | ||
173 | |||
174 | def SerializePartialToString(self): | ||
175 | """Serializes the protocol message to a binary string. | ||
176 | |||
177 | This method is similar to SerializeToString but doesn't check if the | ||
178 | message is initialized. | ||
179 | |||
180 | Returns: | ||
181 | A string representation of the partial message. | ||
182 | """ | ||
183 | raise NotImplementedError | ||
184 | |||
185 | # TODO(robinson): Decide whether we like these better | ||
186 | # than auto-generated has_foo() and clear_foo() methods | ||
187 | # on the instances themselves. This way is less consistent | ||
188 | # with C++, but it makes reflection-type access easier and | ||
189 | # reduces the number of magically autogenerated things. | ||
190 | # | ||
191 | # TODO(robinson): Be sure to document (and test) exactly | ||
192 | # which field names are accepted here. Are we case-sensitive? | ||
193 | # What do we do with fields that share names with Python keywords | ||
194 | # like 'lambda' and 'yield'? | ||
195 | # | ||
196 | # nnorwitz says: | ||
197 | # """ | ||
198 | # Typically (in python), an underscore is appended to names that are | ||
199 | # keywords. So they would become lambda_ or yield_. | ||
200 | # """ | ||
201 | def ListFields(self, field_name): | ||
202 | """Returns a list of (FieldDescriptor, value) tuples for all | ||
203 | fields in the message which are not empty. A singular field is non-empty | ||
204 | if HasField() would return true, and a repeated field is non-empty if | ||
205 | it contains at least one element. The fields are ordered by field | ||
206 | number""" | ||
207 | raise NotImplementedError | ||
208 | |||
209 | def HasField(self, field_name): | ||
210 | raise NotImplementedError | ||
211 | |||
212 | def ClearField(self, field_name): | ||
213 | raise NotImplementedError | ||
214 | |||
215 | def HasExtension(self, extension_handle): | ||
216 | raise NotImplementedError | ||
217 | |||
218 | def ClearExtension(self, extension_handle): | ||
219 | raise NotImplementedError | ||
220 | |||
221 | def ByteSize(self): | ||
222 | """Returns the serialized size of this message. | ||
223 | Recursively calls ByteSize() on all contained messages. | ||
224 | """ | ||
225 | raise NotImplementedError | ||
226 | |||
227 | def _SetListener(self, message_listener): | ||
228 | """Internal method used by the protocol message implementation. | ||
229 | Clients should not call this directly. | ||
230 | |||
231 | Sets a listener that this message will call on certain state transitions. | ||
232 | |||
233 | The purpose of this method is to register back-edges from children to | ||
234 | parents at runtime, for the purpose of setting "has" bits and | ||
235 | byte-size-dirty bits in the parent and ancestor objects whenever a child or | ||
236 | descendant object is modified. | ||
237 | |||
238 | If the client wants to disconnect this Message from the object tree, she | ||
239 | explicitly sets callback to None. | ||
240 | |||
241 | If message_listener is None, unregisters any existing listener. Otherwise, | ||
242 | message_listener must implement the MessageListener interface in | ||
243 | internal/message_listener.py, and we discard any listener registered | ||
244 | via a previous _SetListener() call. | ||
245 | """ | ||
246 | raise NotImplementedError | ||
diff --git a/froofle/protobuf/reflection.py b/froofle/protobuf/reflection.py deleted file mode 100644 index e2abff04..00000000 --- a/froofle/protobuf/reflection.py +++ /dev/null | |||
@@ -1,1653 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | # This code is meant to work on Python 2.4 and above only. | ||
32 | # | ||
33 | # TODO(robinson): Helpers for verbose, common checks like seeing if a | ||
34 | # descriptor's cpp_type is CPPTYPE_MESSAGE. | ||
35 | |||
36 | """Contains a metaclass and helper functions used to create | ||
37 | protocol message classes from Descriptor objects at runtime. | ||
38 | |||
39 | Recall that a metaclass is the "type" of a class. | ||
40 | (A class is to a metaclass what an instance is to a class.) | ||
41 | |||
42 | In this case, we use the GeneratedProtocolMessageType metaclass | ||
43 | to inject all the useful functionality into the classes | ||
44 | output by the protocol compiler at compile-time. | ||
45 | |||
46 | The upshot of all this is that the real implementation | ||
47 | details for ALL pure-Python protocol buffers are *here in | ||
48 | this file*. | ||
49 | """ | ||
50 | |||
51 | __author__ = 'robinson@google.com (Will Robinson)' | ||
52 | |||
53 | import heapq | ||
54 | import threading | ||
55 | import weakref | ||
56 | # We use "as" to avoid name collisions with variables. | ||
57 | from froofle.protobuf.internal import decoder | ||
58 | from froofle.protobuf.internal import encoder | ||
59 | from froofle.protobuf.internal import message_listener as message_listener_mod | ||
60 | from froofle.protobuf.internal import type_checkers | ||
61 | from froofle.protobuf.internal import wire_format | ||
62 | from froofle.protobuf import descriptor as descriptor_mod | ||
63 | from froofle.protobuf import message as message_mod | ||
64 | |||
65 | _FieldDescriptor = descriptor_mod.FieldDescriptor | ||
66 | |||
67 | |||
68 | class GeneratedProtocolMessageType(type): | ||
69 | |||
70 | """Metaclass for protocol message classes created at runtime from Descriptors. | ||
71 | |||
72 | We add implementations for all methods described in the Message class. We | ||
73 | also create properties to allow getting/setting all fields in the protocol | ||
74 | message. Finally, we create slots to prevent users from accidentally | ||
75 | "setting" nonexistent fields in the protocol message, which then wouldn't get | ||
76 | serialized / deserialized properly. | ||
77 | |||
78 | The protocol compiler currently uses this metaclass to create protocol | ||
79 | message classes at runtime. Clients can also manually create their own | ||
80 | classes at runtime, as in this example: | ||
81 | |||
82 | mydescriptor = Descriptor(.....) | ||
83 | class MyProtoClass(Message): | ||
84 | __metaclass__ = GeneratedProtocolMessageType | ||
85 | DESCRIPTOR = mydescriptor | ||
86 | myproto_instance = MyProtoClass() | ||
87 | myproto.foo_field = 23 | ||
88 | ... | ||
89 | """ | ||
90 | |||
91 | # Must be consistent with the protocol-compiler code in | ||
92 | # proto2/compiler/internal/generator.*. | ||
93 | _DESCRIPTOR_KEY = 'DESCRIPTOR' | ||
94 | |||
95 | def __new__(cls, name, bases, dictionary): | ||
96 | """Custom allocation for runtime-generated class types. | ||
97 | |||
98 | We override __new__ because this is apparently the only place | ||
99 | where we can meaningfully set __slots__ on the class we're creating(?). | ||
100 | (The interplay between metaclasses and slots is not very well-documented). | ||
101 | |||
102 | Args: | ||
103 | name: Name of the class (ignored, but required by the | ||
104 | metaclass protocol). | ||
105 | bases: Base classes of the class we're constructing. | ||
106 | (Should be message.Message). We ignore this field, but | ||
107 | it's required by the metaclass protocol | ||
108 | dictionary: The class dictionary of the class we're | ||
109 | constructing. dictionary[_DESCRIPTOR_KEY] must contain | ||
110 | a Descriptor object describing this protocol message | ||
111 | type. | ||
112 | |||
113 | Returns: | ||
114 | Newly-allocated class. | ||
115 | """ | ||
116 | descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] | ||
117 | _AddSlots(descriptor, dictionary) | ||
118 | _AddClassAttributesForNestedExtensions(descriptor, dictionary) | ||
119 | superclass = super(GeneratedProtocolMessageType, cls) | ||
120 | return superclass.__new__(cls, name, bases, dictionary) | ||
121 | |||
122 | def __init__(cls, name, bases, dictionary): | ||
123 | """Here we perform the majority of our work on the class. | ||
124 | We add enum getters, an __init__ method, implementations | ||
125 | of all Message methods, and properties for all fields | ||
126 | in the protocol type. | ||
127 | |||
128 | Args: | ||
129 | name: Name of the class (ignored, but required by the | ||
130 | metaclass protocol). | ||
131 | bases: Base classes of the class we're constructing. | ||
132 | (Should be message.Message). We ignore this field, but | ||
133 | it's required by the metaclass protocol | ||
134 | dictionary: The class dictionary of the class we're | ||
135 | constructing. dictionary[_DESCRIPTOR_KEY] must contain | ||
136 | a Descriptor object describing this protocol message | ||
137 | type. | ||
138 | """ | ||
139 | descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] | ||
140 | # We act as a "friend" class of the descriptor, setting | ||
141 | # its _concrete_class attribute the first time we use a | ||
142 | # given descriptor to initialize a concrete protocol message | ||
143 | # class. | ||
144 | concrete_class_attr_name = '_concrete_class' | ||
145 | if not hasattr(descriptor, concrete_class_attr_name): | ||
146 | setattr(descriptor, concrete_class_attr_name, cls) | ||
147 | cls._known_extensions = [] | ||
148 | _AddEnumValues(descriptor, cls) | ||
149 | _AddInitMethod(descriptor, cls) | ||
150 | _AddPropertiesForFields(descriptor, cls) | ||
151 | _AddStaticMethods(cls) | ||
152 | _AddMessageMethods(descriptor, cls) | ||
153 | _AddPrivateHelperMethods(cls) | ||
154 | superclass = super(GeneratedProtocolMessageType, cls) | ||
155 | superclass.__init__(cls, name, bases, dictionary) | ||
156 | |||
157 | |||
158 | # Stateless helpers for GeneratedProtocolMessageType below. | ||
159 | # Outside clients should not access these directly. | ||
160 | # | ||
161 | # I opted not to make any of these methods on the metaclass, to make it more | ||
162 | # clear that I'm not really using any state there and to keep clients from | ||
163 | # thinking that they have direct access to these construction helpers. | ||
164 | |||
165 | |||
166 | def _PropertyName(proto_field_name): | ||
167 | """Returns the name of the public property attribute which | ||
168 | clients can use to get and (in some cases) set the value | ||
169 | of a protocol message field. | ||
170 | |||
171 | Args: | ||
172 | proto_field_name: The protocol message field name, exactly | ||
173 | as it appears (or would appear) in a .proto file. | ||
174 | """ | ||
175 | # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. | ||
176 | # nnorwitz makes my day by writing: | ||
177 | # """ | ||
178 | # FYI. See the keyword module in the stdlib. This could be as simple as: | ||
179 | # | ||
180 | # if keyword.iskeyword(proto_field_name): | ||
181 | # return proto_field_name + "_" | ||
182 | # return proto_field_name | ||
183 | # """ | ||
184 | return proto_field_name | ||
185 | |||
186 | |||
187 | def _ValueFieldName(proto_field_name): | ||
188 | """Returns the name of the (internal) instance attribute which objects | ||
189 | should use to store the current value for a given protocol message field. | ||
190 | |||
191 | Args: | ||
192 | proto_field_name: The protocol message field name, exactly | ||
193 | as it appears (or would appear) in a .proto file. | ||
194 | """ | ||
195 | return '_value_' + proto_field_name | ||
196 | |||
197 | |||
198 | def _HasFieldName(proto_field_name): | ||
199 | """Returns the name of the (internal) instance attribute which | ||
200 | objects should use to store a boolean telling whether this field | ||
201 | is explicitly set or not. | ||
202 | |||
203 | Args: | ||
204 | proto_field_name: The protocol message field name, exactly | ||
205 | as it appears (or would appear) in a .proto file. | ||
206 | """ | ||
207 | return '_has_' + proto_field_name | ||
208 | |||
209 | |||
210 | def _AddSlots(message_descriptor, dictionary): | ||
211 | """Adds a __slots__ entry to dictionary, containing the names of all valid | ||
212 | attributes for this message type. | ||
213 | |||
214 | Args: | ||
215 | message_descriptor: A Descriptor instance describing this message type. | ||
216 | dictionary: Class dictionary to which we'll add a '__slots__' entry. | ||
217 | """ | ||
218 | field_names = [_ValueFieldName(f.name) for f in message_descriptor.fields] | ||
219 | field_names.extend(_HasFieldName(f.name) for f in message_descriptor.fields | ||
220 | if f.label != _FieldDescriptor.LABEL_REPEATED) | ||
221 | field_names.extend(('Extensions', | ||
222 | '_cached_byte_size', | ||
223 | '_cached_byte_size_dirty', | ||
224 | '_called_transition_to_nonempty', | ||
225 | '_listener', | ||
226 | '_lock', '__weakref__')) | ||
227 | dictionary['__slots__'] = field_names | ||
228 | |||
229 | |||
230 | def _AddClassAttributesForNestedExtensions(descriptor, dictionary): | ||
231 | extension_dict = descriptor.extensions_by_name | ||
232 | for extension_name, extension_field in extension_dict.iteritems(): | ||
233 | assert extension_name not in dictionary | ||
234 | dictionary[extension_name] = extension_field | ||
235 | |||
236 | |||
237 | def _AddEnumValues(descriptor, cls): | ||
238 | """Sets class-level attributes for all enum fields defined in this message. | ||
239 | |||
240 | Args: | ||
241 | descriptor: Descriptor object for this message type. | ||
242 | cls: Class we're constructing for this message type. | ||
243 | """ | ||
244 | for enum_type in descriptor.enum_types: | ||
245 | for enum_value in enum_type.values: | ||
246 | setattr(cls, enum_value.name, enum_value.number) | ||
247 | |||
248 | |||
249 | def _DefaultValueForField(message, field): | ||
250 | """Returns a default value for a field. | ||
251 | |||
252 | Args: | ||
253 | message: Message instance containing this field, or a weakref proxy | ||
254 | of same. | ||
255 | field: FieldDescriptor object for this field. | ||
256 | |||
257 | Returns: A default value for this field. May refer back to |message| | ||
258 | via a weak reference. | ||
259 | """ | ||
260 | # TODO(robinson): Only the repeated fields need a reference to 'message' (so | ||
261 | # that they can set the 'has' bit on the containing Message when someone | ||
262 | # append()s a value). We could special-case this, and avoid an extra | ||
263 | # function call on __init__() and Clear() for non-repeated fields. | ||
264 | |||
265 | # TODO(robinson): Find a better place for the default value assertion in this | ||
266 | # function. No need to repeat them every time the client calls Clear('foo'). | ||
267 | # (We should probably just assert these things once and as early as possible, | ||
268 | # by tightening checking in the descriptor classes.) | ||
269 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
270 | if field.default_value != []: | ||
271 | raise ValueError('Repeated field default value not empty list: %s' % ( | ||
272 | field.default_value)) | ||
273 | listener = _Listener(message, None) | ||
274 | if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
275 | # We can't look at _concrete_class yet since it might not have | ||
276 | # been set. (Depends on order in which we initialize the classes). | ||
277 | return _RepeatedCompositeFieldContainer(listener, field.message_type) | ||
278 | else: | ||
279 | return _RepeatedScalarFieldContainer( | ||
280 | listener, type_checkers.GetTypeChecker(field.cpp_type, field.type)) | ||
281 | |||
282 | if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
283 | assert field.default_value is None | ||
284 | |||
285 | return field.default_value | ||
286 | |||
287 | |||
288 | def _AddInitMethod(message_descriptor, cls): | ||
289 | """Adds an __init__ method to cls.""" | ||
290 | fields = message_descriptor.fields | ||
291 | def init(self): | ||
292 | self._cached_byte_size = 0 | ||
293 | self._cached_byte_size_dirty = False | ||
294 | self._listener = message_listener_mod.NullMessageListener() | ||
295 | self._called_transition_to_nonempty = False | ||
296 | # TODO(robinson): We should only create a lock if we really need one | ||
297 | # in this class. | ||
298 | self._lock = threading.Lock() | ||
299 | for field in fields: | ||
300 | default_value = _DefaultValueForField(self, field) | ||
301 | python_field_name = _ValueFieldName(field.name) | ||
302 | setattr(self, python_field_name, default_value) | ||
303 | if field.label != _FieldDescriptor.LABEL_REPEATED: | ||
304 | setattr(self, _HasFieldName(field.name), False) | ||
305 | self.Extensions = _ExtensionDict(self, cls._known_extensions) | ||
306 | |||
307 | init.__module__ = None | ||
308 | init.__doc__ = None | ||
309 | cls.__init__ = init | ||
310 | |||
311 | |||
312 | def _AddPropertiesForFields(descriptor, cls): | ||
313 | """Adds properties for all fields in this protocol message type.""" | ||
314 | for field in descriptor.fields: | ||
315 | _AddPropertiesForField(field, cls) | ||
316 | |||
317 | |||
318 | def _AddPropertiesForField(field, cls): | ||
319 | """Adds a public property for a protocol message field. | ||
320 | Clients can use this property to get and (in the case | ||
321 | of non-repeated scalar fields) directly set the value | ||
322 | of a protocol message field. | ||
323 | |||
324 | Args: | ||
325 | field: A FieldDescriptor for this field. | ||
326 | cls: The class we're constructing. | ||
327 | """ | ||
328 | # Catch it if we add other types that we should | ||
329 | # handle specially here. | ||
330 | assert _FieldDescriptor.MAX_CPPTYPE == 10 | ||
331 | |||
332 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
333 | _AddPropertiesForRepeatedField(field, cls) | ||
334 | elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
335 | _AddPropertiesForNonRepeatedCompositeField(field, cls) | ||
336 | else: | ||
337 | _AddPropertiesForNonRepeatedScalarField(field, cls) | ||
338 | |||
339 | |||
340 | def _AddPropertiesForRepeatedField(field, cls): | ||
341 | """Adds a public property for a "repeated" protocol message field. Clients | ||
342 | can use this property to get the value of the field, which will be either a | ||
343 | _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see | ||
344 | below). | ||
345 | |||
346 | Note that when clients add values to these containers, we perform | ||
347 | type-checking in the case of repeated scalar fields, and we also set any | ||
348 | necessary "has" bits as a side-effect. | ||
349 | |||
350 | Args: | ||
351 | field: A FieldDescriptor for this field. | ||
352 | cls: The class we're constructing. | ||
353 | """ | ||
354 | proto_field_name = field.name | ||
355 | python_field_name = _ValueFieldName(proto_field_name) | ||
356 | property_name = _PropertyName(proto_field_name) | ||
357 | |||
358 | def getter(self): | ||
359 | return getattr(self, python_field_name) | ||
360 | getter.__module__ = None | ||
361 | getter.__doc__ = 'Getter for %s.' % proto_field_name | ||
362 | |||
363 | # We define a setter just so we can throw an exception with a more | ||
364 | # helpful error message. | ||
365 | def setter(self, new_value): | ||
366 | raise AttributeError('Assignment not allowed to repeated field ' | ||
367 | '"%s" in protocol message object.' % proto_field_name) | ||
368 | |||
369 | doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name | ||
370 | setattr(cls, property_name, property(getter, setter, doc=doc)) | ||
371 | |||
372 | |||
373 | def _AddPropertiesForNonRepeatedScalarField(field, cls): | ||
374 | """Adds a public property for a nonrepeated, scalar protocol message field. | ||
375 | Clients can use this property to get and directly set the value of the field. | ||
376 | Note that when the client sets the value of a field by using this property, | ||
377 | all necessary "has" bits are set as a side-effect, and we also perform | ||
378 | type-checking. | ||
379 | |||
380 | Args: | ||
381 | field: A FieldDescriptor for this field. | ||
382 | cls: The class we're constructing. | ||
383 | """ | ||
384 | proto_field_name = field.name | ||
385 | python_field_name = _ValueFieldName(proto_field_name) | ||
386 | has_field_name = _HasFieldName(proto_field_name) | ||
387 | property_name = _PropertyName(proto_field_name) | ||
388 | type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) | ||
389 | |||
390 | def getter(self): | ||
391 | return getattr(self, python_field_name) | ||
392 | getter.__module__ = None | ||
393 | getter.__doc__ = 'Getter for %s.' % proto_field_name | ||
394 | def setter(self, new_value): | ||
395 | type_checker.CheckValue(new_value) | ||
396 | setattr(self, has_field_name, True) | ||
397 | self._MarkByteSizeDirty() | ||
398 | self._MaybeCallTransitionToNonemptyCallback() | ||
399 | setattr(self, python_field_name, new_value) | ||
400 | setter.__module__ = None | ||
401 | setter.__doc__ = 'Setter for %s.' % proto_field_name | ||
402 | |||
403 | # Add a property to encapsulate the getter/setter. | ||
404 | doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name | ||
405 | setattr(cls, property_name, property(getter, setter, doc=doc)) | ||
406 | |||
407 | |||
408 | def _AddPropertiesForNonRepeatedCompositeField(field, cls): | ||
409 | """Adds a public property for a nonrepeated, composite protocol message field. | ||
410 | A composite field is a "group" or "message" field. | ||
411 | |||
412 | Clients can use this property to get the value of the field, but cannot | ||
413 | assign to the property directly. | ||
414 | |||
415 | Args: | ||
416 | field: A FieldDescriptor for this field. | ||
417 | cls: The class we're constructing. | ||
418 | """ | ||
419 | # TODO(robinson): Remove duplication with similar method | ||
420 | # for non-repeated scalars. | ||
421 | proto_field_name = field.name | ||
422 | python_field_name = _ValueFieldName(proto_field_name) | ||
423 | has_field_name = _HasFieldName(proto_field_name) | ||
424 | property_name = _PropertyName(proto_field_name) | ||
425 | message_type = field.message_type | ||
426 | |||
427 | def getter(self): | ||
428 | # TODO(robinson): Appropriately scary note about double-checked locking. | ||
429 | field_value = getattr(self, python_field_name) | ||
430 | if field_value is None: | ||
431 | self._lock.acquire() | ||
432 | try: | ||
433 | field_value = getattr(self, python_field_name) | ||
434 | if field_value is None: | ||
435 | field_class = message_type._concrete_class | ||
436 | field_value = field_class() | ||
437 | field_value._SetListener(_Listener(self, has_field_name)) | ||
438 | setattr(self, python_field_name, field_value) | ||
439 | finally: | ||
440 | self._lock.release() | ||
441 | return field_value | ||
442 | getter.__module__ = None | ||
443 | getter.__doc__ = 'Getter for %s.' % proto_field_name | ||
444 | |||
445 | # We define a setter just so we can throw an exception with a more | ||
446 | # helpful error message. | ||
447 | def setter(self, new_value): | ||
448 | raise AttributeError('Assignment not allowed to composite field ' | ||
449 | '"%s" in protocol message object.' % proto_field_name) | ||
450 | |||
451 | # Add a property to encapsulate the getter. | ||
452 | doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name | ||
453 | setattr(cls, property_name, property(getter, setter, doc=doc)) | ||
454 | |||
455 | |||
456 | def _AddStaticMethods(cls): | ||
457 | # TODO(robinson): This probably needs to be thread-safe(?) | ||
458 | def RegisterExtension(extension_handle): | ||
459 | extension_handle.containing_type = cls.DESCRIPTOR | ||
460 | cls._known_extensions.append(extension_handle) | ||
461 | cls.RegisterExtension = staticmethod(RegisterExtension) | ||
462 | |||
463 | |||
464 | def _AddListFieldsMethod(message_descriptor, cls): | ||
465 | """Helper for _AddMessageMethods().""" | ||
466 | |||
467 | # Ensure that we always list in ascending field-number order. | ||
468 | # For non-extension fields, we can do the sort once, here, at import-time. | ||
469 | # For extensions, we sort on each ListFields() call, though | ||
470 | # we could do better if we have to. | ||
471 | fields = sorted(message_descriptor.fields, key=lambda f: f.number) | ||
472 | has_field_names = (_HasFieldName(f.name) for f in fields) | ||
473 | value_field_names = (_ValueFieldName(f.name) for f in fields) | ||
474 | triplets = zip(has_field_names, value_field_names, fields) | ||
475 | |||
476 | def ListFields(self): | ||
477 | # We need to list all extension and non-extension fields | ||
478 | # together, in sorted order by field number. | ||
479 | |||
480 | # Step 0: Get an iterator over all "set" non-extension fields, | ||
481 | # sorted by field number. | ||
482 | # This iterator yields (field_number, field_descriptor, value) tuples. | ||
483 | def SortedSetFieldsIter(): | ||
484 | # Note that triplets is already sorted by field number. | ||
485 | for has_field_name, value_field_name, field_descriptor in triplets: | ||
486 | if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED: | ||
487 | value = getattr(self, _ValueFieldName(field_descriptor.name)) | ||
488 | if len(value) > 0: | ||
489 | yield (field_descriptor.number, field_descriptor, value) | ||
490 | elif getattr(self, _HasFieldName(field_descriptor.name)): | ||
491 | value = getattr(self, _ValueFieldName(field_descriptor.name)) | ||
492 | yield (field_descriptor.number, field_descriptor, value) | ||
493 | sorted_fields = SortedSetFieldsIter() | ||
494 | |||
495 | # Step 1: Get an iterator over all "set" extension fields, | ||
496 | # sorted by field number. | ||
497 | # This iterator ALSO yields (field_number, field_descriptor, value) tuples. | ||
498 | # TODO(robinson): It's not necessary to repeat this with each | ||
499 | # serialization call. We can do better. | ||
500 | sorted_extension_fields = sorted( | ||
501 | [(f.number, f, v) for f, v in self.Extensions._ListSetExtensions()]) | ||
502 | |||
503 | # Step 2: Create a composite iterator that merges the extension- | ||
504 | # and non-extension fields, and that still yields fields in | ||
505 | # sorted order. | ||
506 | all_set_fields = _ImergeSorted(sorted_fields, sorted_extension_fields) | ||
507 | |||
508 | # Step 3: Strip off the field numbers and return. | ||
509 | return [field[1:] for field in all_set_fields] | ||
510 | |||
511 | cls.ListFields = ListFields | ||
512 | |||
513 | def _AddHasFieldMethod(cls): | ||
514 | """Helper for _AddMessageMethods().""" | ||
515 | def HasField(self, field_name): | ||
516 | try: | ||
517 | return getattr(self, _HasFieldName(field_name)) | ||
518 | except AttributeError: | ||
519 | raise ValueError('Protocol message has no "%s" field.' % field_name) | ||
520 | cls.HasField = HasField | ||
521 | |||
522 | |||
523 | def _AddClearFieldMethod(cls): | ||
524 | """Helper for _AddMessageMethods().""" | ||
525 | def ClearField(self, field_name): | ||
526 | try: | ||
527 | field = self.DESCRIPTOR.fields_by_name[field_name] | ||
528 | except KeyError: | ||
529 | raise ValueError('Protocol message has no "%s" field.' % field_name) | ||
530 | proto_field_name = field.name | ||
531 | python_field_name = _ValueFieldName(proto_field_name) | ||
532 | has_field_name = _HasFieldName(proto_field_name) | ||
533 | default_value = _DefaultValueForField(self, field) | ||
534 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
535 | self._MarkByteSizeDirty() | ||
536 | else: | ||
537 | if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
538 | old_field_value = getattr(self, python_field_name) | ||
539 | if old_field_value is not None: | ||
540 | # Snip the old object out of the object tree. | ||
541 | old_field_value._SetListener(None) | ||
542 | if getattr(self, has_field_name): | ||
543 | setattr(self, has_field_name, False) | ||
544 | # Set dirty bit on ourself and parents only if | ||
545 | # we're actually changing state. | ||
546 | self._MarkByteSizeDirty() | ||
547 | setattr(self, python_field_name, default_value) | ||
548 | cls.ClearField = ClearField | ||
549 | |||
550 | |||
551 | def _AddClearExtensionMethod(cls): | ||
552 | """Helper for _AddMessageMethods().""" | ||
553 | def ClearExtension(self, extension_handle): | ||
554 | self.Extensions._ClearExtension(extension_handle) | ||
555 | cls.ClearExtension = ClearExtension | ||
556 | |||
557 | |||
558 | def _AddClearMethod(cls): | ||
559 | """Helper for _AddMessageMethods().""" | ||
560 | def Clear(self): | ||
561 | # Clear fields. | ||
562 | fields = self.DESCRIPTOR.fields | ||
563 | for field in fields: | ||
564 | self.ClearField(field.name) | ||
565 | # Clear extensions. | ||
566 | extensions = self.Extensions._ListSetExtensions() | ||
567 | for extension in extensions: | ||
568 | self.ClearExtension(extension[0]) | ||
569 | cls.Clear = Clear | ||
570 | |||
571 | |||
572 | def _AddHasExtensionMethod(cls): | ||
573 | """Helper for _AddMessageMethods().""" | ||
574 | def HasExtension(self, extension_handle): | ||
575 | return self.Extensions._HasExtension(extension_handle) | ||
576 | cls.HasExtension = HasExtension | ||
577 | |||
578 | |||
579 | def _AddEqualsMethod(message_descriptor, cls): | ||
580 | """Helper for _AddMessageMethods().""" | ||
581 | def __eq__(self, other): | ||
582 | if self is other: | ||
583 | return True | ||
584 | |||
585 | # Compare all fields contained directly in this message. | ||
586 | for field_descriptor in message_descriptor.fields: | ||
587 | label = field_descriptor.label | ||
588 | property_name = _PropertyName(field_descriptor.name) | ||
589 | # Non-repeated field equality requires matching "has" bits as well | ||
590 | # as having an equal value. | ||
591 | if label != _FieldDescriptor.LABEL_REPEATED: | ||
592 | self_has = self.HasField(property_name) | ||
593 | other_has = other.HasField(property_name) | ||
594 | if self_has != other_has: | ||
595 | return False | ||
596 | if not self_has: | ||
597 | # If the "has" bit for this field is False, we must stop here. | ||
598 | # Otherwise we will recurse forever on recursively-defined protos. | ||
599 | continue | ||
600 | if getattr(self, property_name) != getattr(other, property_name): | ||
601 | return False | ||
602 | |||
603 | # Compare the extensions present in both messages. | ||
604 | return self.Extensions == other.Extensions | ||
605 | cls.__eq__ = __eq__ | ||
606 | |||
607 | |||
608 | def _AddSetListenerMethod(cls): | ||
609 | """Helper for _AddMessageMethods().""" | ||
610 | def SetListener(self, listener): | ||
611 | if listener is None: | ||
612 | self._listener = message_listener_mod.NullMessageListener() | ||
613 | else: | ||
614 | self._listener = listener | ||
615 | cls._SetListener = SetListener | ||
616 | |||
617 | |||
618 | def _BytesForNonRepeatedElement(value, field_number, field_type): | ||
619 | """Returns the number of bytes needed to serialize a non-repeated element. | ||
620 | The returned byte count includes space for tag information and any | ||
621 | other additional space associated with serializing value. | ||
622 | |||
623 | Args: | ||
624 | value: Value we're serializing. | ||
625 | field_number: Field number of this value. (Since the field number | ||
626 | is stored as part of a varint-encoded tag, this has an impact | ||
627 | on the total bytes required to serialize the value). | ||
628 | field_type: The type of the field. One of the TYPE_* constants | ||
629 | within FieldDescriptor. | ||
630 | """ | ||
631 | try: | ||
632 | fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] | ||
633 | return fn(field_number, value) | ||
634 | except KeyError: | ||
635 | raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) | ||
636 | |||
637 | |||
638 | def _AddByteSizeMethod(message_descriptor, cls): | ||
639 | """Helper for _AddMessageMethods().""" | ||
640 | |||
641 | def BytesForField(message, field, value): | ||
642 | """Returns the number of bytes required to serialize a single field | ||
643 | in message. The field may be repeated or not, composite or not. | ||
644 | |||
645 | Args: | ||
646 | message: The Message instance containing a field of the given type. | ||
647 | field: A FieldDescriptor describing the field of interest. | ||
648 | value: The value whose byte size we're interested in. | ||
649 | |||
650 | Returns: The number of bytes required to serialize the current value | ||
651 | of "field" in "message", including space for tags and any other | ||
652 | necessary information. | ||
653 | """ | ||
654 | |||
655 | if _MessageSetField(field): | ||
656 | return wire_format.MessageSetItemByteSize(field.number, value) | ||
657 | |||
658 | field_number, field_type = field.number, field.type | ||
659 | |||
660 | # Repeated fields. | ||
661 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
662 | elements = value | ||
663 | else: | ||
664 | elements = [value] | ||
665 | |||
666 | size = sum(_BytesForNonRepeatedElement(element, field_number, field_type) | ||
667 | for element in elements) | ||
668 | return size | ||
669 | |||
670 | fields = message_descriptor.fields | ||
671 | has_field_names = (_HasFieldName(f.name) for f in fields) | ||
672 | zipped = zip(has_field_names, fields) | ||
673 | |||
674 | def ByteSize(self): | ||
675 | if not self._cached_byte_size_dirty: | ||
676 | return self._cached_byte_size | ||
677 | |||
678 | size = 0 | ||
679 | # Hardcoded fields first. | ||
680 | for has_field_name, field in zipped: | ||
681 | if (field.label == _FieldDescriptor.LABEL_REPEATED | ||
682 | or getattr(self, has_field_name)): | ||
683 | value = getattr(self, _ValueFieldName(field.name)) | ||
684 | size += BytesForField(self, field, value) | ||
685 | # Extensions next. | ||
686 | for field, value in self.Extensions._ListSetExtensions(): | ||
687 | size += BytesForField(self, field, value) | ||
688 | |||
689 | self._cached_byte_size = size | ||
690 | self._cached_byte_size_dirty = False | ||
691 | return size | ||
692 | cls.ByteSize = ByteSize | ||
693 | |||
694 | |||
695 | def _MessageSetField(field_descriptor): | ||
696 | """Checks if a field should be serialized using the message set wire format. | ||
697 | |||
698 | Args: | ||
699 | field_descriptor: Descriptor of the field. | ||
700 | |||
701 | Returns: | ||
702 | True if the field should be serialized using the message set wire format, | ||
703 | false otherwise. | ||
704 | """ | ||
705 | return (field_descriptor.is_extension and | ||
706 | field_descriptor.label != _FieldDescriptor.LABEL_REPEATED and | ||
707 | field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and | ||
708 | field_descriptor.containing_type.GetOptions().message_set_wire_format) | ||
709 | |||
710 | |||
711 | def _SerializeValueToEncoder(value, field_number, field_descriptor, encoder): | ||
712 | """Appends the serialization of a single value to encoder. | ||
713 | |||
714 | Args: | ||
715 | value: Value to serialize. | ||
716 | field_number: Field number of this value. | ||
717 | field_descriptor: Descriptor of the field to serialize. | ||
718 | encoder: encoder.Encoder object to which we should serialize this value. | ||
719 | """ | ||
720 | if _MessageSetField(field_descriptor): | ||
721 | encoder.AppendMessageSetItem(field_number, value) | ||
722 | return | ||
723 | |||
724 | try: | ||
725 | method = type_checkers.TYPE_TO_SERIALIZE_METHOD[field_descriptor.type] | ||
726 | method(encoder, field_number, value) | ||
727 | except KeyError: | ||
728 | raise message_mod.EncodeError('Unrecognized field type: %d' % | ||
729 | field_descriptor.type) | ||
730 | |||
731 | |||
732 | def _ImergeSorted(*streams): | ||
733 | """Merges N sorted iterators into a single sorted iterator. | ||
734 | Each element in streams must be an iterable that yields | ||
735 | its elements in sorted order, and the elements contained | ||
736 | in each stream must all be comparable. | ||
737 | |||
738 | There may be repeated elements in the component streams or | ||
739 | across the streams; the repeated elements will all be repeated | ||
740 | in the merged iterator as well. | ||
741 | |||
742 | I believe that the heapq module at HEAD in the Python | ||
743 | sources has a method like this, but for now we roll our own. | ||
744 | """ | ||
745 | iters = [iter(stream) for stream in streams] | ||
746 | heap = [] | ||
747 | for index, it in enumerate(iters): | ||
748 | try: | ||
749 | heap.append((it.next(), index)) | ||
750 | except StopIteration: | ||
751 | pass | ||
752 | heapq.heapify(heap) | ||
753 | |||
754 | while heap: | ||
755 | smallest_value, idx = heap[0] | ||
756 | yield smallest_value | ||
757 | try: | ||
758 | next_element = iters[idx].next() | ||
759 | heapq.heapreplace(heap, (next_element, idx)) | ||
760 | except StopIteration: | ||
761 | heapq.heappop(heap) | ||
762 | |||
763 | |||
764 | def _AddSerializeToStringMethod(message_descriptor, cls): | ||
765 | """Helper for _AddMessageMethods().""" | ||
766 | |||
767 | def SerializeToString(self): | ||
768 | # Check if the message has all of its required fields set. | ||
769 | errors = [] | ||
770 | if not _InternalIsInitialized(self, errors): | ||
771 | raise message_mod.EncodeError('\n'.join(errors)) | ||
772 | return self.SerializePartialToString() | ||
773 | cls.SerializeToString = SerializeToString | ||
774 | |||
775 | |||
776 | def _AddSerializePartialToStringMethod(message_descriptor, cls): | ||
777 | """Helper for _AddMessageMethods().""" | ||
778 | Encoder = encoder.Encoder | ||
779 | |||
780 | def SerializePartialToString(self): | ||
781 | encoder = Encoder() | ||
782 | # We need to serialize all extension and non-extension fields | ||
783 | # together, in sorted order by field number. | ||
784 | for field_descriptor, field_value in self.ListFields(): | ||
785 | if field_descriptor.label == _FieldDescriptor.LABEL_REPEATED: | ||
786 | repeated_value = field_value | ||
787 | else: | ||
788 | repeated_value = [field_value] | ||
789 | for element in repeated_value: | ||
790 | _SerializeValueToEncoder(element, field_descriptor.number, | ||
791 | field_descriptor, encoder) | ||
792 | return encoder.ToString() | ||
793 | cls.SerializePartialToString = SerializePartialToString | ||
794 | |||
795 | |||
796 | def _WireTypeForFieldType(field_type): | ||
797 | """Given a field type, returns the expected wire type.""" | ||
798 | try: | ||
799 | return type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_type] | ||
800 | except KeyError: | ||
801 | raise message_mod.DecodeError('Unknown field type: %d' % field_type) | ||
802 | |||
803 | |||
804 | def _RecursivelyMerge(field_number, field_type, decoder, message): | ||
805 | """Decodes a message from decoder into message. | ||
806 | message is either a group or a nested message within some containing | ||
807 | protocol message. If it's a group, we use the group protocol to | ||
808 | deserialize, and if it's a nested message, we use the nested-message | ||
809 | protocol. | ||
810 | |||
811 | Args: | ||
812 | field_number: The field number of message in its enclosing protocol buffer. | ||
813 | field_type: The field type of message. Must be either TYPE_MESSAGE | ||
814 | or TYPE_GROUP. | ||
815 | decoder: Decoder to read from. | ||
816 | message: Message to deserialize into. | ||
817 | """ | ||
818 | if field_type == _FieldDescriptor.TYPE_MESSAGE: | ||
819 | decoder.ReadMessageInto(message) | ||
820 | elif field_type == _FieldDescriptor.TYPE_GROUP: | ||
821 | decoder.ReadGroupInto(field_number, message) | ||
822 | else: | ||
823 | raise message_mod.DecodeError('Unexpected field type: %d' % field_type) | ||
824 | |||
825 | |||
826 | def _DeserializeScalarFromDecoder(field_type, decoder): | ||
827 | """Deserializes a scalar of the requested type from decoder. field_type must | ||
828 | be a scalar (non-group, non-message) FieldDescriptor.FIELD_* constant. | ||
829 | """ | ||
830 | try: | ||
831 | method = type_checkers.TYPE_TO_DESERIALIZE_METHOD[field_type] | ||
832 | return method(decoder) | ||
833 | except KeyError: | ||
834 | raise message_mod.DecodeError('Unrecognized field type: %d' % field_type) | ||
835 | |||
836 | |||
837 | def _SkipField(field_number, wire_type, decoder): | ||
838 | """Skips a field with the specified wire type. | ||
839 | |||
840 | Args: | ||
841 | field_number: Tag number of the field to skip. | ||
842 | wire_type: Wire type of the field to skip. | ||
843 | decoder: Decoder used to deserialize the messsage. It must be positioned | ||
844 | just after reading the the tag and wire type of the field. | ||
845 | """ | ||
846 | if wire_type == wire_format.WIRETYPE_VARINT: | ||
847 | decoder.ReadUInt64() | ||
848 | elif wire_type == wire_format.WIRETYPE_FIXED64: | ||
849 | decoder.ReadFixed64() | ||
850 | elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: | ||
851 | decoder.SkipBytes(decoder.ReadInt32()) | ||
852 | elif wire_type == wire_format.WIRETYPE_START_GROUP: | ||
853 | _SkipGroup(field_number, decoder) | ||
854 | elif wire_type == wire_format.WIRETYPE_END_GROUP: | ||
855 | pass | ||
856 | elif wire_type == wire_format.WIRETYPE_FIXED32: | ||
857 | decoder.ReadFixed32() | ||
858 | else: | ||
859 | raise message_mod.DecodeError('Unexpected wire type: %d' % wire_type) | ||
860 | |||
861 | |||
862 | def _SkipGroup(group_number, decoder): | ||
863 | """Skips a nested group from the decoder. | ||
864 | |||
865 | Args: | ||
866 | group_number: Tag number of the group to skip. | ||
867 | decoder: Decoder used to deserialize the message. It must be positioned | ||
868 | exactly at the beginning of the message that should be skipped. | ||
869 | """ | ||
870 | while True: | ||
871 | field_number, wire_type = decoder.ReadFieldNumberAndWireType() | ||
872 | if (wire_type == wire_format.WIRETYPE_END_GROUP and | ||
873 | field_number == group_number): | ||
874 | return | ||
875 | _SkipField(field_number, wire_type, decoder) | ||
876 | |||
877 | |||
878 | def _DeserializeMessageSetItem(message, decoder): | ||
879 | """Deserializes a message using the message set wire format. | ||
880 | |||
881 | Args: | ||
882 | message: Message to be parsed to. | ||
883 | decoder: The decoder to be used to deserialize encoded data. Note that the | ||
884 | decoder should be positioned just after reading the START_GROUP tag that | ||
885 | began the messageset item. | ||
886 | """ | ||
887 | field_number, wire_type = decoder.ReadFieldNumberAndWireType() | ||
888 | if wire_type != wire_format.WIRETYPE_VARINT or field_number != 2: | ||
889 | raise message_mod.DecodeError( | ||
890 | 'Incorrect message set wire format. ' | ||
891 | 'wire_type: %d, field_number: %d' % (wire_type, field_number)) | ||
892 | |||
893 | type_id = decoder.ReadInt32() | ||
894 | field_number, wire_type = decoder.ReadFieldNumberAndWireType() | ||
895 | if wire_type != wire_format.WIRETYPE_LENGTH_DELIMITED or field_number != 3: | ||
896 | raise message_mod.DecodeError( | ||
897 | 'Incorrect message set wire format. ' | ||
898 | 'wire_type: %d, field_number: %d' % (wire_type, field_number)) | ||
899 | |||
900 | extension_dict = message.Extensions | ||
901 | extensions_by_number = extension_dict._AllExtensionsByNumber() | ||
902 | if type_id not in extensions_by_number: | ||
903 | _SkipField(field_number, wire_type, decoder) | ||
904 | return | ||
905 | |||
906 | field_descriptor = extensions_by_number[type_id] | ||
907 | value = extension_dict[field_descriptor] | ||
908 | decoder.ReadMessageInto(value) | ||
909 | # Read the END_GROUP tag. | ||
910 | field_number, wire_type = decoder.ReadFieldNumberAndWireType() | ||
911 | if wire_type != wire_format.WIRETYPE_END_GROUP or field_number != 1: | ||
912 | raise message_mod.DecodeError( | ||
913 | 'Incorrect message set wire format. ' | ||
914 | 'wire_type: %d, field_number: %d' % (wire_type, field_number)) | ||
915 | |||
916 | |||
917 | def _DeserializeOneEntity(message_descriptor, message, decoder): | ||
918 | """Deserializes the next wire entity from decoder into message. | ||
919 | The next wire entity is either a scalar or a nested message, | ||
920 | and may also be an element in a repeated field (the wire encoding | ||
921 | is the same). | ||
922 | |||
923 | Args: | ||
924 | message_descriptor: A Descriptor instance describing all fields | ||
925 | in message. | ||
926 | message: The Message instance into which we're decoding our fields. | ||
927 | decoder: The Decoder we're using to deserialize encoded data. | ||
928 | |||
929 | Returns: The number of bytes read from decoder during this method. | ||
930 | """ | ||
931 | initial_position = decoder.Position() | ||
932 | field_number, wire_type = decoder.ReadFieldNumberAndWireType() | ||
933 | extension_dict = message.Extensions | ||
934 | extensions_by_number = extension_dict._AllExtensionsByNumber() | ||
935 | if field_number in message_descriptor.fields_by_number: | ||
936 | # Non-extension field. | ||
937 | field_descriptor = message_descriptor.fields_by_number[field_number] | ||
938 | value = getattr(message, _PropertyName(field_descriptor.name)) | ||
939 | def nonextension_setter_fn(scalar): | ||
940 | setattr(message, _PropertyName(field_descriptor.name), scalar) | ||
941 | scalar_setter_fn = nonextension_setter_fn | ||
942 | elif field_number in extensions_by_number: | ||
943 | # Extension field. | ||
944 | field_descriptor = extensions_by_number[field_number] | ||
945 | value = extension_dict[field_descriptor] | ||
946 | def extension_setter_fn(scalar): | ||
947 | extension_dict[field_descriptor] = scalar | ||
948 | scalar_setter_fn = extension_setter_fn | ||
949 | elif wire_type == wire_format.WIRETYPE_END_GROUP: | ||
950 | # We assume we're being parsed as the group that's ended. | ||
951 | return 0 | ||
952 | elif (wire_type == wire_format.WIRETYPE_START_GROUP and | ||
953 | field_number == 1 and | ||
954 | message_descriptor.GetOptions().message_set_wire_format): | ||
955 | # A Message Set item. | ||
956 | _DeserializeMessageSetItem(message, decoder) | ||
957 | return decoder.Position() - initial_position | ||
958 | else: | ||
959 | _SkipField(field_number, wire_type, decoder) | ||
960 | return decoder.Position() - initial_position | ||
961 | |||
962 | # If we reach this point, we've identified the field as either | ||
963 | # hardcoded or extension, and set |field_descriptor|, |scalar_setter_fn|, | ||
964 | # and |value| appropriately. Now actually deserialize the thing. | ||
965 | # | ||
966 | # field_descriptor: Describes the field we're deserializing. | ||
967 | # value: The value currently stored in the field to deserialize. | ||
968 | # Used only if the field is composite and/or repeated. | ||
969 | # scalar_setter_fn: A function F such that F(scalar) will | ||
970 | # set a nonrepeated scalar value for this field. Used only | ||
971 | # if this field is a nonrepeated scalar. | ||
972 | |||
973 | field_number = field_descriptor.number | ||
974 | field_type = field_descriptor.type | ||
975 | expected_wire_type = _WireTypeForFieldType(field_type) | ||
976 | if wire_type != expected_wire_type: | ||
977 | # Need to fill in uninterpreted_bytes. Work for the next CL. | ||
978 | raise RuntimeError('TODO(robinson): Wiretype mismatches not handled.') | ||
979 | |||
980 | property_name = _PropertyName(field_descriptor.name) | ||
981 | label = field_descriptor.label | ||
982 | cpp_type = field_descriptor.cpp_type | ||
983 | |||
984 | # Nonrepeated scalar. Just set the field directly. | ||
985 | if (label != _FieldDescriptor.LABEL_REPEATED | ||
986 | and cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): | ||
987 | scalar_setter_fn(_DeserializeScalarFromDecoder(field_type, decoder)) | ||
988 | return decoder.Position() - initial_position | ||
989 | |||
990 | # Nonrepeated composite. Recursively deserialize. | ||
991 | if label != _FieldDescriptor.LABEL_REPEATED: | ||
992 | composite = value | ||
993 | _RecursivelyMerge(field_number, field_type, decoder, composite) | ||
994 | return decoder.Position() - initial_position | ||
995 | |||
996 | # Now we know we're dealing with a repeated field of some kind. | ||
997 | element_list = value | ||
998 | |||
999 | if cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE: | ||
1000 | # Repeated scalar. | ||
1001 | element_list.append(_DeserializeScalarFromDecoder(field_type, decoder)) | ||
1002 | return decoder.Position() - initial_position | ||
1003 | else: | ||
1004 | # Repeated composite. | ||
1005 | composite = element_list.add() | ||
1006 | _RecursivelyMerge(field_number, field_type, decoder, composite) | ||
1007 | return decoder.Position() - initial_position | ||
1008 | |||
1009 | |||
1010 | def _FieldOrExtensionValues(message, field_or_extension): | ||
1011 | """Retrieves the list of values for the specified field or extension. | ||
1012 | |||
1013 | The target field or extension can be optional, required or repeated, but it | ||
1014 | must have value(s) set. The assumption is that the target field or extension | ||
1015 | is set (e.g. _HasFieldOrExtension holds true). | ||
1016 | |||
1017 | Args: | ||
1018 | message: Message which contains the target field or extension. | ||
1019 | field_or_extension: Field or extension for which the list of values is | ||
1020 | required. Must be an instance of FieldDescriptor. | ||
1021 | |||
1022 | Returns: | ||
1023 | A list of values for the specified field or extension. This list will only | ||
1024 | contain a single element if the field is non-repeated. | ||
1025 | """ | ||
1026 | if field_or_extension.is_extension: | ||
1027 | value = message.Extensions[field_or_extension] | ||
1028 | else: | ||
1029 | value = getattr(message, _ValueFieldName(field_or_extension.name)) | ||
1030 | if field_or_extension.label != _FieldDescriptor.LABEL_REPEATED: | ||
1031 | return [value] | ||
1032 | else: | ||
1033 | # In this case value is a list or repeated values. | ||
1034 | return value | ||
1035 | |||
1036 | |||
1037 | def _HasFieldOrExtension(message, field_or_extension): | ||
1038 | """Checks if a message has the specified field or extension set. | ||
1039 | |||
1040 | The field or extension specified can be optional, required or repeated. If | ||
1041 | it is repeated, this function returns True. Otherwise it checks the has bit | ||
1042 | of the field or extension. | ||
1043 | |||
1044 | Args: | ||
1045 | message: Message which contains the target field or extension. | ||
1046 | field_or_extension: Field or extension to check. This must be a | ||
1047 | FieldDescriptor instance. | ||
1048 | |||
1049 | Returns: | ||
1050 | True if the message has a value set for the specified field or extension, | ||
1051 | or if the field or extension is repeated. | ||
1052 | """ | ||
1053 | if field_or_extension.label == _FieldDescriptor.LABEL_REPEATED: | ||
1054 | return True | ||
1055 | if field_or_extension.is_extension: | ||
1056 | return message.HasExtension(field_or_extension) | ||
1057 | else: | ||
1058 | return message.HasField(field_or_extension.name) | ||
1059 | |||
1060 | |||
1061 | def _IsFieldOrExtensionInitialized(message, field, errors=None): | ||
1062 | """Checks if a message field or extension is initialized. | ||
1063 | |||
1064 | Args: | ||
1065 | message: The message which contains the field or extension. | ||
1066 | field: Field or extension to check. This must be a FieldDescriptor instance. | ||
1067 | errors: Errors will be appended to it, if set to a meaningful value. | ||
1068 | |||
1069 | Returns: | ||
1070 | True if the field/extension can be considered initialized. | ||
1071 | """ | ||
1072 | # If the field is required and is not set, it isn't initialized. | ||
1073 | if field.label == _FieldDescriptor.LABEL_REQUIRED: | ||
1074 | if not _HasFieldOrExtension(message, field): | ||
1075 | if errors is not None: | ||
1076 | errors.append('Required field %s is not set.' % field.full_name) | ||
1077 | return False | ||
1078 | |||
1079 | # If the field is optional and is not set, or if it | ||
1080 | # isn't a submessage then the field is initialized. | ||
1081 | if field.label == _FieldDescriptor.LABEL_OPTIONAL: | ||
1082 | if not _HasFieldOrExtension(message, field): | ||
1083 | return True | ||
1084 | if field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE: | ||
1085 | return True | ||
1086 | |||
1087 | # The field is set and is either a single or a repeated submessage. | ||
1088 | messages = _FieldOrExtensionValues(message, field) | ||
1089 | # If all submessages in this field are initialized, the field is | ||
1090 | # considered initialized. | ||
1091 | for message in messages: | ||
1092 | if not _InternalIsInitialized(message, errors): | ||
1093 | return False | ||
1094 | return True | ||
1095 | |||
1096 | |||
1097 | def _InternalIsInitialized(message, errors=None): | ||
1098 | """Checks if all required fields of a message are set. | ||
1099 | |||
1100 | Args: | ||
1101 | message: The message to check. | ||
1102 | errors: If set, initialization errors will be appended to it. | ||
1103 | |||
1104 | Returns: | ||
1105 | True iff the specified message has all required fields set. | ||
1106 | """ | ||
1107 | fields_and_extensions = [] | ||
1108 | fields_and_extensions.extend(message.DESCRIPTOR.fields) | ||
1109 | fields_and_extensions.extend( | ||
1110 | [extension[0] for extension in message.Extensions._ListSetExtensions()]) | ||
1111 | for field_or_extension in fields_and_extensions: | ||
1112 | if not _IsFieldOrExtensionInitialized(message, field_or_extension, errors): | ||
1113 | return False | ||
1114 | return True | ||
1115 | |||
1116 | |||
1117 | def _AddMergeFromStringMethod(message_descriptor, cls): | ||
1118 | """Helper for _AddMessageMethods().""" | ||
1119 | Decoder = decoder.Decoder | ||
1120 | def MergeFromString(self, serialized): | ||
1121 | decoder = Decoder(serialized) | ||
1122 | byte_count = 0 | ||
1123 | while not decoder.EndOfStream(): | ||
1124 | bytes_read = _DeserializeOneEntity(message_descriptor, self, decoder) | ||
1125 | if not bytes_read: | ||
1126 | break | ||
1127 | byte_count += bytes_read | ||
1128 | return byte_count | ||
1129 | cls.MergeFromString = MergeFromString | ||
1130 | |||
1131 | |||
1132 | def _AddIsInitializedMethod(cls): | ||
1133 | """Adds the IsInitialized method to the protocol message class.""" | ||
1134 | cls.IsInitialized = _InternalIsInitialized | ||
1135 | |||
1136 | |||
1137 | def _MergeFieldOrExtension(destination_msg, field, value): | ||
1138 | """Merges a specified message field into another message.""" | ||
1139 | property_name = _PropertyName(field.name) | ||
1140 | is_extension = field.is_extension | ||
1141 | |||
1142 | if not is_extension: | ||
1143 | destination = getattr(destination_msg, property_name) | ||
1144 | elif (field.label == _FieldDescriptor.LABEL_REPEATED or | ||
1145 | field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): | ||
1146 | destination = destination_msg.Extensions[field] | ||
1147 | |||
1148 | # Case 1 - a composite field. | ||
1149 | if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
1150 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
1151 | for v in value: | ||
1152 | destination.add().MergeFrom(v) | ||
1153 | else: | ||
1154 | destination.MergeFrom(value) | ||
1155 | return | ||
1156 | |||
1157 | # Case 2 - a repeated field. | ||
1158 | if field.label == _FieldDescriptor.LABEL_REPEATED: | ||
1159 | for v in value: | ||
1160 | destination.append(v) | ||
1161 | return | ||
1162 | |||
1163 | # Case 3 - a singular field. | ||
1164 | if is_extension: | ||
1165 | destination_msg.Extensions[field] = value | ||
1166 | else: | ||
1167 | setattr(destination_msg, property_name, value) | ||
1168 | |||
1169 | |||
1170 | def _AddMergeFromMethod(cls): | ||
1171 | def MergeFrom(self, msg): | ||
1172 | assert msg is not self | ||
1173 | for field in msg.ListFields(): | ||
1174 | _MergeFieldOrExtension(self, field[0], field[1]) | ||
1175 | cls.MergeFrom = MergeFrom | ||
1176 | |||
1177 | |||
1178 | def _AddMessageMethods(message_descriptor, cls): | ||
1179 | """Adds implementations of all Message methods to cls.""" | ||
1180 | _AddListFieldsMethod(message_descriptor, cls) | ||
1181 | _AddHasFieldMethod(cls) | ||
1182 | _AddClearFieldMethod(cls) | ||
1183 | _AddClearExtensionMethod(cls) | ||
1184 | _AddClearMethod(cls) | ||
1185 | _AddHasExtensionMethod(cls) | ||
1186 | _AddEqualsMethod(message_descriptor, cls) | ||
1187 | _AddSetListenerMethod(cls) | ||
1188 | _AddByteSizeMethod(message_descriptor, cls) | ||
1189 | _AddSerializeToStringMethod(message_descriptor, cls) | ||
1190 | _AddSerializePartialToStringMethod(message_descriptor, cls) | ||
1191 | _AddMergeFromStringMethod(message_descriptor, cls) | ||
1192 | _AddIsInitializedMethod(cls) | ||
1193 | _AddMergeFromMethod(cls) | ||
1194 | |||
1195 | |||
1196 | def _AddPrivateHelperMethods(cls): | ||
1197 | """Adds implementation of private helper methods to cls.""" | ||
1198 | |||
1199 | def MaybeCallTransitionToNonemptyCallback(self): | ||
1200 | """Calls self._listener.TransitionToNonempty() the first time this | ||
1201 | method is called. On all subsequent calls, this is a no-op. | ||
1202 | """ | ||
1203 | if not self._called_transition_to_nonempty: | ||
1204 | self._listener.TransitionToNonempty() | ||
1205 | self._called_transition_to_nonempty = True | ||
1206 | cls._MaybeCallTransitionToNonemptyCallback = ( | ||
1207 | MaybeCallTransitionToNonemptyCallback) | ||
1208 | |||
1209 | def MarkByteSizeDirty(self): | ||
1210 | """Sets the _cached_byte_size_dirty bit to true, | ||
1211 | and propagates this to our listener iff this was a state change. | ||
1212 | """ | ||
1213 | if not self._cached_byte_size_dirty: | ||
1214 | self._cached_byte_size_dirty = True | ||
1215 | self._listener.ByteSizeDirty() | ||
1216 | cls._MarkByteSizeDirty = MarkByteSizeDirty | ||
1217 | |||
1218 | |||
1219 | class _Listener(object): | ||
1220 | |||
1221 | """MessageListener implementation that a parent message registers with its | ||
1222 | child message. | ||
1223 | |||
1224 | In order to support semantics like: | ||
1225 | |||
1226 | foo.bar.baz = 23 | ||
1227 | assert foo.HasField('bar') | ||
1228 | |||
1229 | ...child objects must have back references to their parents. | ||
1230 | This helper class is at the heart of this support. | ||
1231 | """ | ||
1232 | |||
1233 | def __init__(self, parent_message, has_field_name): | ||
1234 | """Args: | ||
1235 | parent_message: The message whose _MaybeCallTransitionToNonemptyCallback() | ||
1236 | and _MarkByteSizeDirty() methods we should call when we receive | ||
1237 | TransitionToNonempty() and ByteSizeDirty() messages. | ||
1238 | has_field_name: The name of the "has" field that we should set in | ||
1239 | the parent message when we receive a TransitionToNonempty message, | ||
1240 | or None if there's no "has" field to set. (This will be the case | ||
1241 | for child objects in "repeated" fields). | ||
1242 | """ | ||
1243 | # This listener establishes a back reference from a child (contained) object | ||
1244 | # to its parent (containing) object. We make this a weak reference to avoid | ||
1245 | # creating cyclic garbage when the client finishes with the 'parent' object | ||
1246 | # in the tree. | ||
1247 | if isinstance(parent_message, weakref.ProxyType): | ||
1248 | self._parent_message_weakref = parent_message | ||
1249 | else: | ||
1250 | self._parent_message_weakref = weakref.proxy(parent_message) | ||
1251 | self._has_field_name = has_field_name | ||
1252 | |||
1253 | def TransitionToNonempty(self): | ||
1254 | try: | ||
1255 | if self._has_field_name is not None: | ||
1256 | setattr(self._parent_message_weakref, self._has_field_name, True) | ||
1257 | # Propagate the signal to our parents iff this is the first field set. | ||
1258 | self._parent_message_weakref._MaybeCallTransitionToNonemptyCallback() | ||
1259 | except ReferenceError: | ||
1260 | # We can get here if a client has kept a reference to a child object, | ||
1261 | # and is now setting a field on it, but the child's parent has been | ||
1262 | # garbage-collected. This is not an error. | ||
1263 | pass | ||
1264 | |||
1265 | def ByteSizeDirty(self): | ||
1266 | try: | ||
1267 | self._parent_message_weakref._MarkByteSizeDirty() | ||
1268 | except ReferenceError: | ||
1269 | # Same as above. | ||
1270 | pass | ||
1271 | |||
1272 | |||
1273 | # TODO(robinson): Move elsewhere? | ||
1274 | # TODO(robinson): Provide a clear() method here in addition to ClearField()? | ||
1275 | class _RepeatedScalarFieldContainer(object): | ||
1276 | |||
1277 | """Simple, type-checked, list-like container for holding repeated scalars.""" | ||
1278 | |||
1279 | # Minimizes memory usage and disallows assignment to other attributes. | ||
1280 | __slots__ = ['_message_listener', '_type_checker', '_values'] | ||
1281 | |||
1282 | def __init__(self, message_listener, type_checker): | ||
1283 | """ | ||
1284 | Args: | ||
1285 | message_listener: A MessageListener implementation. | ||
1286 | The _RepeatedScalarFieldContaininer will call this object's | ||
1287 | TransitionToNonempty() method when it transitions from being empty to | ||
1288 | being nonempty. | ||
1289 | type_checker: A _ValueChecker instance to run on elements inserted | ||
1290 | into this container. | ||
1291 | """ | ||
1292 | self._message_listener = message_listener | ||
1293 | self._type_checker = type_checker | ||
1294 | self._values = [] | ||
1295 | |||
1296 | def append(self, elem): | ||
1297 | self._type_checker.CheckValue(elem) | ||
1298 | self._values.append(elem) | ||
1299 | self._message_listener.ByteSizeDirty() | ||
1300 | if len(self._values) == 1: | ||
1301 | self._message_listener.TransitionToNonempty() | ||
1302 | |||
1303 | def remove(self, elem): | ||
1304 | self._values.remove(elem) | ||
1305 | self._message_listener.ByteSizeDirty() | ||
1306 | |||
1307 | # List-like __getitem__() support also makes us iterable (via "iter(foo)" | ||
1308 | # or implicitly via "for i in mylist:") for free. | ||
1309 | def __getitem__(self, key): | ||
1310 | return self._values[key] | ||
1311 | |||
1312 | def __setitem__(self, key, value): | ||
1313 | # No need to call TransitionToNonempty(), since if we're able to | ||
1314 | # set the element at this index, we were already nonempty before | ||
1315 | # this method was called. | ||
1316 | self._message_listener.ByteSizeDirty() | ||
1317 | self._type_checker.CheckValue(value) | ||
1318 | self._values[key] = value | ||
1319 | |||
1320 | def __len__(self): | ||
1321 | return len(self._values) | ||
1322 | |||
1323 | def __eq__(self, other): | ||
1324 | if self is other: | ||
1325 | return True | ||
1326 | # Special case for the same type which should be common and fast. | ||
1327 | if isinstance(other, self.__class__): | ||
1328 | return other._values == self._values | ||
1329 | # We are presumably comparing against some other sequence type. | ||
1330 | return other == self._values | ||
1331 | |||
1332 | def __ne__(self, other): | ||
1333 | # Can't use != here since it would infinitely recurse. | ||
1334 | return not self == other | ||
1335 | |||
1336 | |||
1337 | # TODO(robinson): Move elsewhere? | ||
1338 | # TODO(robinson): Provide a clear() method here in addition to ClearField()? | ||
1339 | # TODO(robinson): Unify common functionality with | ||
1340 | # _RepeatedScalarFieldContaininer? | ||
1341 | class _RepeatedCompositeFieldContainer(object): | ||
1342 | |||
1343 | """Simple, list-like container for holding repeated composite fields.""" | ||
1344 | |||
1345 | # Minimizes memory usage and disallows assignment to other attributes. | ||
1346 | __slots__ = ['_values', '_message_descriptor', '_message_listener'] | ||
1347 | |||
1348 | def __init__(self, message_listener, message_descriptor): | ||
1349 | """Note that we pass in a descriptor instead of the generated directly, | ||
1350 | since at the time we construct a _RepeatedCompositeFieldContainer we | ||
1351 | haven't yet necessarily initialized the type that will be contained in the | ||
1352 | container. | ||
1353 | |||
1354 | Args: | ||
1355 | message_listener: A MessageListener implementation. | ||
1356 | The _RepeatedCompositeFieldContainer will call this object's | ||
1357 | TransitionToNonempty() method when it transitions from being empty to | ||
1358 | being nonempty. | ||
1359 | message_descriptor: A Descriptor instance describing the protocol type | ||
1360 | that should be present in this container. We'll use the | ||
1361 | _concrete_class field of this descriptor when the client calls add(). | ||
1362 | """ | ||
1363 | self._message_listener = message_listener | ||
1364 | self._message_descriptor = message_descriptor | ||
1365 | self._values = [] | ||
1366 | |||
1367 | def add(self): | ||
1368 | new_element = self._message_descriptor._concrete_class() | ||
1369 | new_element._SetListener(self._message_listener) | ||
1370 | self._values.append(new_element) | ||
1371 | self._message_listener.ByteSizeDirty() | ||
1372 | self._message_listener.TransitionToNonempty() | ||
1373 | return new_element | ||
1374 | |||
1375 | def __delitem__(self, key): | ||
1376 | self._message_listener.ByteSizeDirty() | ||
1377 | del self._values[key] | ||
1378 | |||
1379 | # List-like __getitem__() support also makes us iterable (via "iter(foo)" | ||
1380 | # or implicitly via "for i in mylist:") for free. | ||
1381 | def __getitem__(self, key): | ||
1382 | return self._values[key] | ||
1383 | |||
1384 | def __len__(self): | ||
1385 | return len(self._values) | ||
1386 | |||
1387 | def __eq__(self, other): | ||
1388 | if self is other: | ||
1389 | return True | ||
1390 | if not isinstance(other, self.__class__): | ||
1391 | raise TypeError('Can only compare repeated composite fields against ' | ||
1392 | 'other repeated composite fields.') | ||
1393 | return self._values == other._values | ||
1394 | |||
1395 | def __ne__(self, other): | ||
1396 | # Can't use != here since it would infinitely recurse. | ||
1397 | return not self == other | ||
1398 | |||
1399 | # TODO(robinson): Implement, document, and test slicing support. | ||
1400 | |||
1401 | |||
1402 | # TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... | ||
1403 | # TODO(robinson): Unify error handling of "unknown extension" crap. | ||
1404 | # TODO(robinson): There's so much similarity between the way that | ||
1405 | # extensions behave and the way that normal fields behave that it would | ||
1406 | # be really nice to unify more code. It's not immediately obvious | ||
1407 | # how to do this, though, and I'd rather get the full functionality | ||
1408 | # implemented (and, crucially, get all the tests and specs fleshed out | ||
1409 | # and passing), and then come back to this thorny unification problem. | ||
1410 | # TODO(robinson): Support iteritems()-style iteration over all | ||
1411 | # extensions with the "has" bits turned on? | ||
1412 | class _ExtensionDict(object): | ||
1413 | |||
1414 | """Dict-like container for supporting an indexable "Extensions" | ||
1415 | field on proto instances. | ||
1416 | |||
1417 | Note that in all cases we expect extension handles to be | ||
1418 | FieldDescriptors. | ||
1419 | """ | ||
1420 | |||
1421 | class _ExtensionListener(object): | ||
1422 | |||
1423 | """Adapts an _ExtensionDict to behave as a MessageListener.""" | ||
1424 | |||
1425 | def __init__(self, extension_dict, handle_id): | ||
1426 | self._extension_dict = extension_dict | ||
1427 | self._handle_id = handle_id | ||
1428 | |||
1429 | def TransitionToNonempty(self): | ||
1430 | self._extension_dict._SubmessageTransitionedToNonempty(self._handle_id) | ||
1431 | |||
1432 | def ByteSizeDirty(self): | ||
1433 | self._extension_dict._SubmessageByteSizeBecameDirty() | ||
1434 | |||
1435 | # TODO(robinson): Somewhere, we need to blow up if people | ||
1436 | # try to register two extensions with the same field number. | ||
1437 | # (And we need a test for this of course). | ||
1438 | |||
1439 | def __init__(self, extended_message, known_extensions): | ||
1440 | """extended_message: Message instance for which we are the Extensions dict. | ||
1441 | known_extensions: Iterable of known extension handles. | ||
1442 | These must be FieldDescriptors. | ||
1443 | """ | ||
1444 | # We keep a weak reference to extended_message, since | ||
1445 | # it has a reference to this instance in turn. | ||
1446 | self._extended_message = weakref.proxy(extended_message) | ||
1447 | # We make a deep copy of known_extensions to avoid any | ||
1448 | # thread-safety concerns, since the argument passed in | ||
1449 | # is the global (class-level) dict of known extensions for | ||
1450 | # this type of message, which could be modified at any time | ||
1451 | # via a RegisterExtension() call. | ||
1452 | # | ||
1453 | # This dict maps from handle id to handle (a FieldDescriptor). | ||
1454 | # | ||
1455 | # XXX | ||
1456 | # TODO(robinson): This isn't good enough. The client could | ||
1457 | # instantiate an object in module A, then afterward import | ||
1458 | # module B and pass the instance to B.Foo(). If B imports | ||
1459 | # an extender of this proto and then tries to use it, B | ||
1460 | # will get a KeyError, even though the extension *is* registered | ||
1461 | # at the time of use. | ||
1462 | # XXX | ||
1463 | self._known_extensions = dict((id(e), e) for e in known_extensions) | ||
1464 | # Read lock around self._values, which may be modified by multiple | ||
1465 | # concurrent readers in the conceptually "const" __getitem__ method. | ||
1466 | # So, we grab this lock in every "read-only" method to ensure | ||
1467 | # that concurrent read access is safe without external locking. | ||
1468 | self._lock = threading.Lock() | ||
1469 | # Maps from extension handle ID to current value of that extension. | ||
1470 | self._values = {} | ||
1471 | # Maps from extension handle ID to a boolean "has" bit, but only | ||
1472 | # for non-repeated extension fields. | ||
1473 | keys = (id for id, extension in self._known_extensions.iteritems() | ||
1474 | if extension.label != _FieldDescriptor.LABEL_REPEATED) | ||
1475 | self._has_bits = dict.fromkeys(keys, False) | ||
1476 | |||
1477 | def __getitem__(self, extension_handle): | ||
1478 | """Returns the current value of the given extension handle.""" | ||
1479 | # We don't care as much about keeping critical sections short in the | ||
1480 | # extension support, since it's presumably much less of a common case. | ||
1481 | self._lock.acquire() | ||
1482 | try: | ||
1483 | handle_id = id(extension_handle) | ||
1484 | if handle_id not in self._known_extensions: | ||
1485 | raise KeyError('Extension not known to this class') | ||
1486 | if handle_id not in self._values: | ||
1487 | self._AddMissingHandle(extension_handle, handle_id) | ||
1488 | return self._values[handle_id] | ||
1489 | finally: | ||
1490 | self._lock.release() | ||
1491 | |||
1492 | def __eq__(self, other): | ||
1493 | # We have to grab read locks since we're accessing _values | ||
1494 | # in a "const" method. See the comment in the constructor. | ||
1495 | if self is other: | ||
1496 | return True | ||
1497 | self._lock.acquire() | ||
1498 | try: | ||
1499 | other._lock.acquire() | ||
1500 | try: | ||
1501 | if self._has_bits != other._has_bits: | ||
1502 | return False | ||
1503 | # If there's a "has" bit, then only compare values where it is true. | ||
1504 | for k, v in self._values.iteritems(): | ||
1505 | if self._has_bits.get(k, False) and v != other._values[k]: | ||
1506 | return False | ||
1507 | return True | ||
1508 | finally: | ||
1509 | other._lock.release() | ||
1510 | finally: | ||
1511 | self._lock.release() | ||
1512 | |||
1513 | def __ne__(self, other): | ||
1514 | return not self == other | ||
1515 | |||
1516 | # Note that this is only meaningful for non-repeated, scalar extension | ||
1517 | # fields. Note also that we may have to call | ||
1518 | # MaybeCallTransitionToNonemptyCallback() when we do successfully set a field | ||
1519 | # this way, to set any necssary "has" bits in the ancestors of the extended | ||
1520 | # message. | ||
1521 | def __setitem__(self, extension_handle, value): | ||
1522 | """If extension_handle specifies a non-repeated, scalar extension | ||
1523 | field, sets the value of that field. | ||
1524 | """ | ||
1525 | handle_id = id(extension_handle) | ||
1526 | if handle_id not in self._known_extensions: | ||
1527 | raise KeyError('Extension not known to this class') | ||
1528 | field = extension_handle # Just shorten the name. | ||
1529 | if (field.label == _FieldDescriptor.LABEL_OPTIONAL | ||
1530 | and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): | ||
1531 | # It's slightly wasteful to lookup the type checker each time, | ||
1532 | # but we expect this to be a vanishingly uncommon case anyway. | ||
1533 | type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) | ||
1534 | type_checker.CheckValue(value) | ||
1535 | self._values[handle_id] = value | ||
1536 | self._has_bits[handle_id] = True | ||
1537 | self._extended_message._MarkByteSizeDirty() | ||
1538 | self._extended_message._MaybeCallTransitionToNonemptyCallback() | ||
1539 | else: | ||
1540 | raise TypeError('Extension is repeated and/or a composite type.') | ||
1541 | |||
1542 | def _AddMissingHandle(self, extension_handle, handle_id): | ||
1543 | """Helper internal to ExtensionDict.""" | ||
1544 | # Special handling for non-repeated message extensions, which (like | ||
1545 | # normal fields of this kind) are initialized lazily. | ||
1546 | # REQUIRES: _lock already held. | ||
1547 | cpp_type = extension_handle.cpp_type | ||
1548 | label = extension_handle.label | ||
1549 | if (cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE | ||
1550 | and label != _FieldDescriptor.LABEL_REPEATED): | ||
1551 | self._AddMissingNonRepeatedCompositeHandle(extension_handle, handle_id) | ||
1552 | else: | ||
1553 | self._values[handle_id] = _DefaultValueForField( | ||
1554 | self._extended_message, extension_handle) | ||
1555 | |||
1556 | def _AddMissingNonRepeatedCompositeHandle(self, extension_handle, handle_id): | ||
1557 | """Helper internal to ExtensionDict.""" | ||
1558 | # REQUIRES: _lock already held. | ||
1559 | value = extension_handle.message_type._concrete_class() | ||
1560 | value._SetListener(_ExtensionDict._ExtensionListener(self, handle_id)) | ||
1561 | self._values[handle_id] = value | ||
1562 | |||
1563 | def _SubmessageTransitionedToNonempty(self, handle_id): | ||
1564 | """Called when a submessage with a given handle id first transitions to | ||
1565 | being nonempty. Called by _ExtensionListener. | ||
1566 | """ | ||
1567 | assert handle_id in self._has_bits | ||
1568 | self._has_bits[handle_id] = True | ||
1569 | self._extended_message._MaybeCallTransitionToNonemptyCallback() | ||
1570 | |||
1571 | def _SubmessageByteSizeBecameDirty(self): | ||
1572 | """Called whenever a submessage's cached byte size becomes invalid | ||
1573 | (goes from being "clean" to being "dirty"). Called by _ExtensionListener. | ||
1574 | """ | ||
1575 | self._extended_message._MarkByteSizeDirty() | ||
1576 | |||
1577 | # We may wish to widen the public interface of Message.Extensions | ||
1578 | # to expose some of this private functionality in the future. | ||
1579 | # For now, we make all this functionality module-private and just | ||
1580 | # implement what we need for serialization/deserialization, | ||
1581 | # HasField()/ClearField(), etc. | ||
1582 | |||
1583 | def _HasExtension(self, extension_handle): | ||
1584 | """Method for internal use by this module. | ||
1585 | Returns true iff we "have" this extension in the sense of the | ||
1586 | "has" bit being set. | ||
1587 | """ | ||
1588 | handle_id = id(extension_handle) | ||
1589 | # Note that this is different from the other checks. | ||
1590 | if handle_id not in self._has_bits: | ||
1591 | raise KeyError('Extension not known to this class, or is repeated field.') | ||
1592 | return self._has_bits[handle_id] | ||
1593 | |||
1594 | # Intentionally pretty similar to ClearField() above. | ||
1595 | def _ClearExtension(self, extension_handle): | ||
1596 | """Method for internal use by this module. | ||
1597 | Clears the specified extension, unsetting its "has" bit. | ||
1598 | """ | ||
1599 | handle_id = id(extension_handle) | ||
1600 | if handle_id not in self._known_extensions: | ||
1601 | raise KeyError('Extension not known to this class') | ||
1602 | default_value = _DefaultValueForField(self._extended_message, | ||
1603 | extension_handle) | ||
1604 | if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: | ||
1605 | self._extended_message._MarkByteSizeDirty() | ||
1606 | else: | ||
1607 | cpp_type = extension_handle.cpp_type | ||
1608 | if cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: | ||
1609 | if handle_id in self._values: | ||
1610 | # Future modifications to this object shouldn't set any | ||
1611 | # "has" bits here. | ||
1612 | self._values[handle_id]._SetListener(None) | ||
1613 | if self._has_bits[handle_id]: | ||
1614 | self._has_bits[handle_id] = False | ||
1615 | self._extended_message._MarkByteSizeDirty() | ||
1616 | if handle_id in self._values: | ||
1617 | del self._values[handle_id] | ||
1618 | |||
1619 | def _ListSetExtensions(self): | ||
1620 | """Method for internal use by this module. | ||
1621 | |||
1622 | Returns an sequence of all extensions that are currently "set" | ||
1623 | in this extension dict. A "set" extension is a repeated extension, | ||
1624 | or a non-repeated extension with its "has" bit set. | ||
1625 | |||
1626 | The returned sequence contains (field_descriptor, value) pairs, | ||
1627 | where value is the current value of the extension with the given | ||
1628 | field descriptor. | ||
1629 | |||
1630 | The sequence values are in arbitrary order. | ||
1631 | """ | ||
1632 | self._lock.acquire() # Read-only methods must lock around self._values. | ||
1633 | try: | ||
1634 | set_extensions = [] | ||
1635 | for handle_id, value in self._values.iteritems(): | ||
1636 | handle = self._known_extensions[handle_id] | ||
1637 | if (handle.label == _FieldDescriptor.LABEL_REPEATED | ||
1638 | or self._has_bits[handle_id]): | ||
1639 | set_extensions.append((handle, value)) | ||
1640 | return set_extensions | ||
1641 | finally: | ||
1642 | self._lock.release() | ||
1643 | |||
1644 | def _AllExtensionsByNumber(self): | ||
1645 | """Method for internal use by this module. | ||
1646 | |||
1647 | Returns: A dict mapping field_number to (handle, field_descriptor), | ||
1648 | for *all* registered extensions for this dict. | ||
1649 | """ | ||
1650 | # TODO(robinson): Precompute and store this away. Note that we'll have to | ||
1651 | # be careful when we move away from having _known_extensions as a | ||
1652 | # deep-copied member of this object. | ||
1653 | return dict((f.number, f) for f in self._known_extensions.itervalues()) | ||
diff --git a/froofle/protobuf/service.py b/froofle/protobuf/service.py deleted file mode 100644 index 3989216a..00000000 --- a/froofle/protobuf/service.py +++ /dev/null | |||
@@ -1,208 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Declares the RPC service interfaces. | ||
32 | |||
33 | This module declares the abstract interfaces underlying proto2 RPC | ||
34 | services. These are intented to be independent of any particular RPC | ||
35 | implementation, so that proto2 services can be used on top of a variety | ||
36 | of implementations. | ||
37 | """ | ||
38 | |||
39 | __author__ = 'petar@google.com (Petar Petrov)' | ||
40 | |||
41 | |||
42 | class Service(object): | ||
43 | |||
44 | """Abstract base interface for protocol-buffer-based RPC services. | ||
45 | |||
46 | Services themselves are abstract classes (implemented either by servers or as | ||
47 | stubs), but they subclass this base interface. The methods of this | ||
48 | interface can be used to call the methods of the service without knowing | ||
49 | its exact type at compile time (analogous to the Message interface). | ||
50 | """ | ||
51 | |||
52 | def GetDescriptor(self): | ||
53 | """Retrieves this service's descriptor.""" | ||
54 | raise NotImplementedError | ||
55 | |||
56 | def CallMethod(self, method_descriptor, rpc_controller, | ||
57 | request, done): | ||
58 | """Calls a method of the service specified by method_descriptor. | ||
59 | |||
60 | Preconditions: | ||
61 | * method_descriptor.service == GetDescriptor | ||
62 | * request is of the exact same classes as returned by | ||
63 | GetRequestClass(method). | ||
64 | * After the call has started, the request must not be modified. | ||
65 | * "rpc_controller" is of the correct type for the RPC implementation being | ||
66 | used by this Service. For stubs, the "correct type" depends on the | ||
67 | RpcChannel which the stub is using. | ||
68 | |||
69 | Postconditions: | ||
70 | * "done" will be called when the method is complete. This may be | ||
71 | before CallMethod() returns or it may be at some point in the future. | ||
72 | """ | ||
73 | raise NotImplementedError | ||
74 | |||
75 | def GetRequestClass(self, method_descriptor): | ||
76 | """Returns the class of the request message for the specified method. | ||
77 | |||
78 | CallMethod() requires that the request is of a particular subclass of | ||
79 | Message. GetRequestClass() gets the default instance of this required | ||
80 | type. | ||
81 | |||
82 | Example: | ||
83 | method = service.GetDescriptor().FindMethodByName("Foo") | ||
84 | request = stub.GetRequestClass(method)() | ||
85 | request.ParseFromString(input) | ||
86 | service.CallMethod(method, request, callback) | ||
87 | """ | ||
88 | raise NotImplementedError | ||
89 | |||
90 | def GetResponseClass(self, method_descriptor): | ||
91 | """Returns the class of the response message for the specified method. | ||
92 | |||
93 | This method isn't really needed, as the RpcChannel's CallMethod constructs | ||
94 | the response protocol message. It's provided anyway in case it is useful | ||
95 | for the caller to know the response type in advance. | ||
96 | """ | ||
97 | raise NotImplementedError | ||
98 | |||
99 | |||
100 | class RpcController(object): | ||
101 | |||
102 | """An RpcController mediates a single method call. | ||
103 | |||
104 | The primary purpose of the controller is to provide a way to manipulate | ||
105 | settings specific to the RPC implementation and to find out about RPC-level | ||
106 | errors. The methods provided by the RpcController interface are intended | ||
107 | to be a "least common denominator" set of features which we expect all | ||
108 | implementations to support. Specific implementations may provide more | ||
109 | advanced features (e.g. deadline propagation). | ||
110 | """ | ||
111 | |||
112 | # Client-side methods below | ||
113 | |||
114 | def Reset(self): | ||
115 | """Resets the RpcController to its initial state. | ||
116 | |||
117 | After the RpcController has been reset, it may be reused in | ||
118 | a new call. Must not be called while an RPC is in progress. | ||
119 | """ | ||
120 | raise NotImplementedError | ||
121 | |||
122 | def Failed(self): | ||
123 | """Returns true if the call failed. | ||
124 | |||
125 | After a call has finished, returns true if the call failed. The possible | ||
126 | reasons for failure depend on the RPC implementation. Failed() must not | ||
127 | be called before a call has finished. If Failed() returns true, the | ||
128 | contents of the response message are undefined. | ||
129 | """ | ||
130 | raise NotImplementedError | ||
131 | |||
132 | def ErrorText(self): | ||
133 | """If Failed is true, returns a human-readable description of the error.""" | ||
134 | raise NotImplementedError | ||
135 | |||
136 | def StartCancel(self): | ||
137 | """Initiate cancellation. | ||
138 | |||
139 | Advises the RPC system that the caller desires that the RPC call be | ||
140 | canceled. The RPC system may cancel it immediately, may wait awhile and | ||
141 | then cancel it, or may not even cancel the call at all. If the call is | ||
142 | canceled, the "done" callback will still be called and the RpcController | ||
143 | will indicate that the call failed at that time. | ||
144 | """ | ||
145 | raise NotImplementedError | ||
146 | |||
147 | # Server-side methods below | ||
148 | |||
149 | def SetFailed(self, reason): | ||
150 | """Sets a failure reason. | ||
151 | |||
152 | Causes Failed() to return true on the client side. "reason" will be | ||
153 | incorporated into the message returned by ErrorText(). If you find | ||
154 | you need to return machine-readable information about failures, you | ||
155 | should incorporate it into your response protocol buffer and should | ||
156 | NOT call SetFailed(). | ||
157 | """ | ||
158 | raise NotImplementedError | ||
159 | |||
160 | def IsCanceled(self): | ||
161 | """Checks if the client cancelled the RPC. | ||
162 | |||
163 | If true, indicates that the client canceled the RPC, so the server may | ||
164 | as well give up on replying to it. The server should still call the | ||
165 | final "done" callback. | ||
166 | """ | ||
167 | raise NotImplementedError | ||
168 | |||
169 | def NotifyOnCancel(self, callback): | ||
170 | """Sets a callback to invoke on cancel. | ||
171 | |||
172 | Asks that the given callback be called when the RPC is canceled. The | ||
173 | callback will always be called exactly once. If the RPC completes without | ||
174 | being canceled, the callback will be called after completion. If the RPC | ||
175 | has already been canceled when NotifyOnCancel() is called, the callback | ||
176 | will be called immediately. | ||
177 | |||
178 | NotifyOnCancel() must be called no more than once per request. | ||
179 | """ | ||
180 | raise NotImplementedError | ||
181 | |||
182 | |||
183 | class RpcChannel(object): | ||
184 | |||
185 | """Abstract interface for an RPC channel. | ||
186 | |||
187 | An RpcChannel represents a communication line to a service which can be used | ||
188 | to call that service's methods. The service may be running on another | ||
189 | machine. Normally, you should not use an RpcChannel directly, but instead | ||
190 | construct a stub {@link Service} wrapping it. Example: | ||
191 | |||
192 | Example: | ||
193 | RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234") | ||
194 | RpcController controller = rpcImpl.Controller() | ||
195 | MyService service = MyService_Stub(channel) | ||
196 | service.MyMethod(controller, request, callback) | ||
197 | """ | ||
198 | |||
199 | def CallMethod(self, method_descriptor, rpc_controller, | ||
200 | request, response_class, done): | ||
201 | """Calls the method identified by the descriptor. | ||
202 | |||
203 | Call the given method of the remote service. The signature of this | ||
204 | procedure looks the same as Service.CallMethod(), but the requirements | ||
205 | are less strict in one important way: the request object doesn't have to | ||
206 | be of any specific class as long as its descriptor is method.input_type. | ||
207 | """ | ||
208 | raise NotImplementedError | ||
diff --git a/froofle/protobuf/service_reflection.py b/froofle/protobuf/service_reflection.py deleted file mode 100644 index bdd6bad5..00000000 --- a/froofle/protobuf/service_reflection.py +++ /dev/null | |||
@@ -1,289 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Contains metaclasses used to create protocol service and service stub | ||
32 | classes from ServiceDescriptor objects at runtime. | ||
33 | |||
34 | The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to | ||
35 | inject all useful functionality into the classes output by the protocol | ||
36 | compiler at compile-time. | ||
37 | """ | ||
38 | |||
39 | __author__ = 'petar@google.com (Petar Petrov)' | ||
40 | |||
41 | |||
42 | class GeneratedServiceType(type): | ||
43 | |||
44 | """Metaclass for service classes created at runtime from ServiceDescriptors. | ||
45 | |||
46 | Implementations for all methods described in the Service class are added here | ||
47 | by this class. We also create properties to allow getting/setting all fields | ||
48 | in the protocol message. | ||
49 | |||
50 | The protocol compiler currently uses this metaclass to create protocol service | ||
51 | classes at runtime. Clients can also manually create their own classes at | ||
52 | runtime, as in this example: | ||
53 | |||
54 | mydescriptor = ServiceDescriptor(.....) | ||
55 | class MyProtoService(service.Service): | ||
56 | __metaclass__ = GeneratedServiceType | ||
57 | DESCRIPTOR = mydescriptor | ||
58 | myservice_instance = MyProtoService() | ||
59 | ... | ||
60 | """ | ||
61 | |||
62 | _DESCRIPTOR_KEY = 'DESCRIPTOR' | ||
63 | |||
64 | def __init__(cls, name, bases, dictionary): | ||
65 | """Creates a message service class. | ||
66 | |||
67 | Args: | ||
68 | name: Name of the class (ignored, but required by the metaclass | ||
69 | protocol). | ||
70 | bases: Base classes of the class being constructed. | ||
71 | dictionary: The class dictionary of the class being constructed. | ||
72 | dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object | ||
73 | describing this protocol service type. | ||
74 | """ | ||
75 | # Don't do anything if this class doesn't have a descriptor. This happens | ||
76 | # when a service class is subclassed. | ||
77 | if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: | ||
78 | return | ||
79 | descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] | ||
80 | service_builder = _ServiceBuilder(descriptor) | ||
81 | service_builder.BuildService(cls) | ||
82 | |||
83 | |||
84 | class GeneratedServiceStubType(GeneratedServiceType): | ||
85 | |||
86 | """Metaclass for service stubs created at runtime from ServiceDescriptors. | ||
87 | |||
88 | This class has similar responsibilities as GeneratedServiceType, except that | ||
89 | it creates the service stub classes. | ||
90 | """ | ||
91 | |||
92 | _DESCRIPTOR_KEY = 'DESCRIPTOR' | ||
93 | |||
94 | def __init__(cls, name, bases, dictionary): | ||
95 | """Creates a message service stub class. | ||
96 | |||
97 | Args: | ||
98 | name: Name of the class (ignored, here). | ||
99 | bases: Base classes of the class being constructed. | ||
100 | dictionary: The class dictionary of the class being constructed. | ||
101 | dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object | ||
102 | describing this protocol service type. | ||
103 | """ | ||
104 | super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) | ||
105 | # Don't do anything if this class doesn't have a descriptor. This happens | ||
106 | # when a service stub is subclassed. | ||
107 | if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: | ||
108 | return | ||
109 | descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] | ||
110 | service_stub_builder = _ServiceStubBuilder(descriptor) | ||
111 | service_stub_builder.BuildServiceStub(cls) | ||
112 | |||
113 | |||
114 | class _ServiceBuilder(object): | ||
115 | |||
116 | """This class constructs a protocol service class using a service descriptor. | ||
117 | |||
118 | Given a service descriptor, this class constructs a class that represents | ||
119 | the specified service descriptor. One service builder instance constructs | ||
120 | exactly one service class. That means all instances of that class share the | ||
121 | same builder. | ||
122 | """ | ||
123 | |||
124 | def __init__(self, service_descriptor): | ||
125 | """Initializes an instance of the service class builder. | ||
126 | |||
127 | Args: | ||
128 | service_descriptor: ServiceDescriptor to use when constructing the | ||
129 | service class. | ||
130 | """ | ||
131 | self.descriptor = service_descriptor | ||
132 | |||
133 | def BuildService(self, cls): | ||
134 | """Constructs the service class. | ||
135 | |||
136 | Args: | ||
137 | cls: The class that will be constructed. | ||
138 | """ | ||
139 | |||
140 | # CallMethod needs to operate with an instance of the Service class. This | ||
141 | # internal wrapper function exists only to be able to pass the service | ||
142 | # instance to the method that does the real CallMethod work. | ||
143 | def _WrapCallMethod(srvc, method_descriptor, | ||
144 | rpc_controller, request, callback): | ||
145 | self._CallMethod(srvc, method_descriptor, | ||
146 | rpc_controller, request, callback) | ||
147 | self.cls = cls | ||
148 | cls.CallMethod = _WrapCallMethod | ||
149 | cls.GetDescriptor = self._GetDescriptor | ||
150 | cls.GetRequestClass = self._GetRequestClass | ||
151 | cls.GetResponseClass = self._GetResponseClass | ||
152 | for method in self.descriptor.methods: | ||
153 | setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) | ||
154 | |||
155 | def _GetDescriptor(self): | ||
156 | """Retrieves the service descriptor. | ||
157 | |||
158 | Returns: | ||
159 | The descriptor of the service (of type ServiceDescriptor). | ||
160 | """ | ||
161 | return self.descriptor | ||
162 | |||
163 | def _CallMethod(self, srvc, method_descriptor, | ||
164 | rpc_controller, request, callback): | ||
165 | """Calls the method described by a given method descriptor. | ||
166 | |||
167 | Args: | ||
168 | srvc: Instance of the service for which this method is called. | ||
169 | method_descriptor: Descriptor that represent the method to call. | ||
170 | rpc_controller: RPC controller to use for this method's execution. | ||
171 | request: Request protocol message. | ||
172 | callback: A callback to invoke after the method has completed. | ||
173 | """ | ||
174 | if method_descriptor.containing_service != self.descriptor: | ||
175 | raise RuntimeError( | ||
176 | 'CallMethod() given method descriptor for wrong service type.') | ||
177 | method = getattr(srvc, method_descriptor.name) | ||
178 | method(rpc_controller, request, callback) | ||
179 | |||
180 | def _GetRequestClass(self, method_descriptor): | ||
181 | """Returns the class of the request protocol message. | ||
182 | |||
183 | Args: | ||
184 | method_descriptor: Descriptor of the method for which to return the | ||
185 | request protocol message class. | ||
186 | |||
187 | Returns: | ||
188 | A class that represents the input protocol message of the specified | ||
189 | method. | ||
190 | """ | ||
191 | if method_descriptor.containing_service != self.descriptor: | ||
192 | raise RuntimeError( | ||
193 | 'GetRequestClass() given method descriptor for wrong service type.') | ||
194 | return method_descriptor.input_type._concrete_class | ||
195 | |||
196 | def _GetResponseClass(self, method_descriptor): | ||
197 | """Returns the class of the response protocol message. | ||
198 | |||
199 | Args: | ||
200 | method_descriptor: Descriptor of the method for which to return the | ||
201 | response protocol message class. | ||
202 | |||
203 | Returns: | ||
204 | A class that represents the output protocol message of the specified | ||
205 | method. | ||
206 | """ | ||
207 | if method_descriptor.containing_service != self.descriptor: | ||
208 | raise RuntimeError( | ||
209 | 'GetResponseClass() given method descriptor for wrong service type.') | ||
210 | return method_descriptor.output_type._concrete_class | ||
211 | |||
212 | def _GenerateNonImplementedMethod(self, method): | ||
213 | """Generates and returns a method that can be set for a service methods. | ||
214 | |||
215 | Args: | ||
216 | method: Descriptor of the service method for which a method is to be | ||
217 | generated. | ||
218 | |||
219 | Returns: | ||
220 | A method that can be added to the service class. | ||
221 | """ | ||
222 | return lambda inst, rpc_controller, request, callback: ( | ||
223 | self._NonImplementedMethod(method.name, rpc_controller, callback)) | ||
224 | |||
225 | def _NonImplementedMethod(self, method_name, rpc_controller, callback): | ||
226 | """The body of all methods in the generated service class. | ||
227 | |||
228 | Args: | ||
229 | method_name: Name of the method being executed. | ||
230 | rpc_controller: RPC controller used to execute this method. | ||
231 | callback: A callback which will be invoked when the method finishes. | ||
232 | """ | ||
233 | rpc_controller.SetFailed('Method %s not implemented.' % method_name) | ||
234 | callback(None) | ||
235 | |||
236 | |||
237 | class _ServiceStubBuilder(object): | ||
238 | |||
239 | """Constructs a protocol service stub class using a service descriptor. | ||
240 | |||
241 | Given a service descriptor, this class constructs a suitable stub class. | ||
242 | A stub is just a type-safe wrapper around an RpcChannel which emulates a | ||
243 | local implementation of the service. | ||
244 | |||
245 | One service stub builder instance constructs exactly one class. It means all | ||
246 | instances of that class share the same service stub builder. | ||
247 | """ | ||
248 | |||
249 | def __init__(self, service_descriptor): | ||
250 | """Initializes an instance of the service stub class builder. | ||
251 | |||
252 | Args: | ||
253 | service_descriptor: ServiceDescriptor to use when constructing the | ||
254 | stub class. | ||
255 | """ | ||
256 | self.descriptor = service_descriptor | ||
257 | |||
258 | def BuildServiceStub(self, cls): | ||
259 | """Constructs the stub class. | ||
260 | |||
261 | Args: | ||
262 | cls: The class that will be constructed. | ||
263 | """ | ||
264 | |||
265 | def _ServiceStubInit(stub, rpc_channel): | ||
266 | stub.rpc_channel = rpc_channel | ||
267 | self.cls = cls | ||
268 | cls.__init__ = _ServiceStubInit | ||
269 | for method in self.descriptor.methods: | ||
270 | setattr(cls, method.name, self._GenerateStubMethod(method)) | ||
271 | |||
272 | def _GenerateStubMethod(self, method): | ||
273 | return lambda inst, rpc_controller, request, callback: self._StubMethod( | ||
274 | inst, method, rpc_controller, request, callback) | ||
275 | |||
276 | def _StubMethod(self, stub, method_descriptor, | ||
277 | rpc_controller, request, callback): | ||
278 | """The body of all service methods in the generated stub class. | ||
279 | |||
280 | Args: | ||
281 | stub: Stub instance. | ||
282 | method_descriptor: Descriptor of the invoked method. | ||
283 | rpc_controller: Rpc controller to execute the method. | ||
284 | request: Request protocol message. | ||
285 | callback: A callback to execute when the method finishes. | ||
286 | """ | ||
287 | stub.rpc_channel.CallMethod( | ||
288 | method_descriptor, rpc_controller, request, | ||
289 | method_descriptor.output_type._concrete_class, callback) | ||
diff --git a/froofle/protobuf/text_format.py b/froofle/protobuf/text_format.py deleted file mode 100644 index 1c4cadfc..00000000 --- a/froofle/protobuf/text_format.py +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | # Protocol Buffers - Google's data interchange format | ||
2 | # Copyright 2008 Google Inc. All rights reserved. | ||
3 | # http://code.google.com/p/protobuf/ | ||
4 | # | ||
5 | # Redistribution and use in source and binary forms, with or without | ||
6 | # modification, are permitted provided that the following conditions are | ||
7 | # met: | ||
8 | # | ||
9 | # * Redistributions of source code must retain the above copyright | ||
10 | # notice, this list of conditions and the following disclaimer. | ||
11 | # * Redistributions in binary form must reproduce the above | ||
12 | # copyright notice, this list of conditions and the following disclaimer | ||
13 | # in the documentation and/or other materials provided with the | ||
14 | # distribution. | ||
15 | # * Neither the name of Google Inc. nor the names of its | ||
16 | # contributors may be used to endorse or promote products derived from | ||
17 | # this software without specific prior written permission. | ||
18 | # | ||
19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | |||
31 | """Contains routines for printing protocol messages in text format.""" | ||
32 | |||
33 | __author__ = 'kenton@google.com (Kenton Varda)' | ||
34 | |||
35 | import cStringIO | ||
36 | |||
37 | from froofle.protobuf import descriptor | ||
38 | |||
39 | __all__ = [ 'MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue' ] | ||
40 | |||
41 | def MessageToString(message): | ||
42 | out = cStringIO.StringIO() | ||
43 | PrintMessage(message, out) | ||
44 | result = out.getvalue() | ||
45 | out.close() | ||
46 | return result | ||
47 | |||
48 | def PrintMessage(message, out, indent = 0): | ||
49 | for field, value in message.ListFields(): | ||
50 | if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: | ||
51 | for element in value: | ||
52 | PrintField(field, element, out, indent) | ||
53 | else: | ||
54 | PrintField(field, value, out, indent) | ||
55 | |||
56 | def PrintField(field, value, out, indent = 0): | ||
57 | """Print a single field name/value pair. For repeated fields, the value | ||
58 | should be a single element.""" | ||
59 | |||
60 | out.write(' ' * indent); | ||
61 | if field.is_extension: | ||
62 | out.write('[') | ||
63 | if (field.containing_type.GetOptions().message_set_wire_format and | ||
64 | field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and | ||
65 | field.message_type == field.extension_scope and | ||
66 | field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL): | ||
67 | out.write(field.message_type.full_name) | ||
68 | else: | ||
69 | out.write(field.full_name) | ||
70 | out.write(']') | ||
71 | elif field.type == descriptor.FieldDescriptor.TYPE_GROUP: | ||
72 | # For groups, use the capitalized name. | ||
73 | out.write(field.message_type.name) | ||
74 | else: | ||
75 | out.write(field.name) | ||
76 | |||
77 | if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE: | ||
78 | # The colon is optional in this case, but our cross-language golden files | ||
79 | # don't include it. | ||
80 | out.write(': ') | ||
81 | |||
82 | PrintFieldValue(field, value, out, indent) | ||
83 | out.write('\n') | ||
84 | |||
85 | def PrintFieldValue(field, value, out, indent = 0): | ||
86 | """Print a single field value (not including name). For repeated fields, | ||
87 | the value should be a single element.""" | ||
88 | |||
89 | if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: | ||
90 | out.write(' {\n') | ||
91 | PrintMessage(value, out, indent + 2) | ||
92 | out.write(' ' * indent + '}') | ||
93 | elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: | ||
94 | out.write(field.enum_type.values_by_number[value].name) | ||
95 | elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: | ||
96 | out.write('\"') | ||
97 | out.write(_CEscape(value)) | ||
98 | out.write('\"') | ||
99 | elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: | ||
100 | if value: | ||
101 | out.write("true") | ||
102 | else: | ||
103 | out.write("false") | ||
104 | else: | ||
105 | out.write(str(value)) | ||
106 | |||
107 | # text.encode('string_escape') does not seem to satisfy our needs as it | ||
108 | # encodes unprintable characters using two-digit hex escapes whereas our | ||
109 | # C++ unescaping function allows hex escapes to be any length. So, | ||
110 | # "\0011".encode('string_escape') ends up being "\\x011", which will be | ||
111 | # decoded in C++ as a single-character string with char code 0x11. | ||
112 | def _CEscape(text): | ||
113 | def escape(c): | ||
114 | o = ord(c) | ||
115 | if o == 10: return r"\n" # optional escape | ||
116 | if o == 13: return r"\r" # optional escape | ||
117 | if o == 9: return r"\t" # optional escape | ||
118 | if o == 39: return r"\'" # optional escape | ||
119 | |||
120 | if o == 34: return r'\"' # necessary escape | ||
121 | if o == 92: return r"\\" # necessary escape | ||
122 | |||
123 | if o >= 127 or o < 32: return "\\%03o" % o # necessary escapes | ||
124 | return c | ||
125 | return "".join([escape(c) for c in text]) | ||
diff --git a/gerrit_upload.py b/gerrit_upload.py deleted file mode 100755 index 17112aac..00000000 --- a/gerrit_upload.py +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | # | ||
2 | # Copyright (C) 2008 The Android Open Source Project | ||
3 | # | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | # you may not use this file except in compliance with the License. | ||
6 | # You may obtain a copy of the License at | ||
7 | # | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | # | ||
10 | # Unless required by applicable law or agreed to in writing, software | ||
11 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | # See the License for the specific language governing permissions and | ||
14 | # limitations under the License. | ||
15 | |||
16 | import getpass | ||
17 | import os | ||
18 | import sys | ||
19 | from tempfile import mkstemp | ||
20 | |||
21 | from codereview.proto_client import HttpRpc, Proxy | ||
22 | from codereview.review_pb2 import ReviewService_Stub | ||
23 | from codereview.upload_bundle_pb2 import * | ||
24 | from git_command import GitCommand | ||
25 | from error import UploadError | ||
26 | |||
27 | try: | ||
28 | import readline | ||
29 | except ImportError: | ||
30 | pass | ||
31 | |||
32 | MAX_SEGMENT_SIZE = 1020 * 1024 | ||
33 | |||
34 | def _GetRpcServer(email, server, save_cookies): | ||
35 | """Returns an RpcServer. | ||
36 | |||
37 | Returns: | ||
38 | A new RpcServer, on which RPC calls can be made. | ||
39 | """ | ||
40 | |||
41 | def GetUserCredentials(): | ||
42 | """Prompts the user for a username and password.""" | ||
43 | e = email | ||
44 | if e is None: | ||
45 | e = raw_input("Email: ").strip() | ||
46 | password = getpass.getpass("Password for %s: " % e) | ||
47 | return (e, password) | ||
48 | |||
49 | # If this is the dev_appserver, use fake authentication. | ||
50 | lc_server = server.lower() | ||
51 | if lc_server == "localhost" or lc_server.startswith("localhost:"): | ||
52 | if email is None: | ||
53 | email = "test@example.com" | ||
54 | server = HttpRpc( | ||
55 | server, | ||
56 | lambda: (email, "password"), | ||
57 | extra_headers={"Cookie": | ||
58 | 'dev_appserver_login="%s:False"' % email}) | ||
59 | # Don't try to talk to ClientLogin. | ||
60 | server.authenticated = True | ||
61 | return server | ||
62 | |||
63 | if save_cookies: | ||
64 | cookie_file = ".gerrit_cookies" | ||
65 | else: | ||
66 | cookie_file = None | ||
67 | |||
68 | return HttpRpc(server, GetUserCredentials, | ||
69 | cookie_file=cookie_file) | ||
70 | |||
71 | def UploadBundle(project, | ||
72 | server, | ||
73 | email, | ||
74 | dest_project, | ||
75 | dest_branch, | ||
76 | src_branch, | ||
77 | bases, | ||
78 | people, | ||
79 | replace_changes = None, | ||
80 | save_cookies=True): | ||
81 | |||
82 | srv = _GetRpcServer(email, server, save_cookies) | ||
83 | review = Proxy(ReviewService_Stub(srv)) | ||
84 | tmp_fd, tmp_bundle = mkstemp(".bundle", ".gpq") | ||
85 | os.close(tmp_fd) | ||
86 | |||
87 | srcid = project.bare_git.rev_parse(src_branch) | ||
88 | revlist = project._revlist(src_branch, *bases) | ||
89 | |||
90 | if srcid not in revlist: | ||
91 | # This can happen if src_branch is an annotated tag | ||
92 | # | ||
93 | revlist.append(srcid) | ||
94 | revlist_size = len(revlist) * 42 | ||
95 | |||
96 | try: | ||
97 | cmd = ['bundle', 'create', tmp_bundle, src_branch] | ||
98 | cmd.extend(bases) | ||
99 | if GitCommand(project, cmd).Wait() != 0: | ||
100 | raise UploadError('cannot create bundle') | ||
101 | fd = open(tmp_bundle, "rb") | ||
102 | |||
103 | bundle_id = None | ||
104 | segment_id = 0 | ||
105 | next_data = fd.read(MAX_SEGMENT_SIZE - revlist_size) | ||
106 | |||
107 | while True: | ||
108 | this_data = next_data | ||
109 | next_data = fd.read(MAX_SEGMENT_SIZE) | ||
110 | segment_id += 1 | ||
111 | |||
112 | if bundle_id is None: | ||
113 | req = UploadBundleRequest() | ||
114 | req.dest_project = str(dest_project) | ||
115 | req.dest_branch = str(dest_branch) | ||
116 | for e in people[0]: | ||
117 | req.reviewers.append(e) | ||
118 | for e in people[1]: | ||
119 | req.cc.append(e) | ||
120 | for c in revlist: | ||
121 | req.contained_object.append(c) | ||
122 | if replace_changes: | ||
123 | for change_id,commit_id in replace_changes.iteritems(): | ||
124 | r = req.replace.add() | ||
125 | r.change_id = change_id | ||
126 | r.object_id = commit_id | ||
127 | else: | ||
128 | req = UploadBundleContinue() | ||
129 | req.bundle_id = bundle_id | ||
130 | req.segment_id = segment_id | ||
131 | |||
132 | req.bundle_data = this_data | ||
133 | if len(next_data) > 0: | ||
134 | req.partial_upload = True | ||
135 | else: | ||
136 | req.partial_upload = False | ||
137 | |||
138 | if bundle_id is None: | ||
139 | rsp = review.UploadBundle(req) | ||
140 | else: | ||
141 | rsp = review.ContinueBundle(req) | ||
142 | |||
143 | if rsp.status_code == UploadBundleResponse.CONTINUE: | ||
144 | bundle_id = rsp.bundle_id | ||
145 | elif rsp.status_code == UploadBundleResponse.RECEIVED: | ||
146 | bundle_id = rsp.bundle_id | ||
147 | return bundle_id | ||
148 | else: | ||
149 | if rsp.status_code == UploadBundleResponse.UNKNOWN_PROJECT: | ||
150 | reason = 'unknown project "%s"' % dest_project | ||
151 | elif rsp.status_code == UploadBundleResponse.UNKNOWN_BRANCH: | ||
152 | reason = 'unknown branch "%s"' % dest_branch | ||
153 | elif rsp.status_code == UploadBundleResponse.UNKNOWN_BUNDLE: | ||
154 | reason = 'unknown bundle' | ||
155 | elif rsp.status_code == UploadBundleResponse.NOT_BUNDLE_OWNER: | ||
156 | reason = 'not bundle owner' | ||
157 | elif rsp.status_code == UploadBundleResponse.BUNDLE_CLOSED: | ||
158 | reason = 'bundle closed' | ||
159 | elif rsp.status_code == UploadBundleResponse.UNAUTHORIZED_USER: | ||
160 | reason = ('Unauthorized user. Visit http://%s/hello to sign up.' | ||
161 | % server) | ||
162 | elif rsp.status_code == UploadBundleResponse.UNKNOWN_CHANGE: | ||
163 | reason = 'invalid change id' | ||
164 | elif rsp.status_code == UploadBundleResponse.CHANGE_CLOSED: | ||
165 | reason = 'one or more changes are closed' | ||
166 | elif rsp.status_code == UploadBundleResponse.UNKNOWN_EMAIL: | ||
167 | emails = [x for x in rsp.invalid_reviewers] + [ | ||
168 | x for x in rsp.invalid_cc] | ||
169 | reason = 'invalid email addresses: %s' % ", ".join(emails) | ||
170 | else: | ||
171 | reason = 'unknown error ' + str(rsp.status_code) | ||
172 | raise UploadError(reason) | ||
173 | finally: | ||
174 | os.unlink(tmp_bundle) | ||
@@ -24,10 +24,8 @@ import urllib2 | |||
24 | from color import Coloring | 24 | from color import Coloring |
25 | from git_command import GitCommand | 25 | from git_command import GitCommand |
26 | from git_config import GitConfig, IsId | 26 | from git_config import GitConfig, IsId |
27 | from gerrit_upload import UploadBundle | ||
28 | from error import GitError, ImportError, UploadError | 27 | from error import GitError, ImportError, UploadError |
29 | from remote import Remote | 28 | from remote import Remote |
30 | from codereview import proto_client | ||
31 | 29 | ||
32 | HEAD = 'HEAD' | 30 | HEAD = 'HEAD' |
33 | R_HEADS = 'refs/heads/' | 31 | R_HEADS = 'refs/heads/' |
@@ -481,32 +479,7 @@ class Project(object): | |||
481 | branch.remote.projectname = self.name | 479 | branch.remote.projectname = self.name |
482 | branch.remote.Save() | 480 | branch.remote.Save() |
483 | 481 | ||
484 | if branch.remote.ReviewProtocol == 'http-post': | 482 | if branch.remote.ReviewProtocol == 'ssh': |
485 | base_list = [] | ||
486 | for name, id in self._allrefs.iteritems(): | ||
487 | if branch.remote.WritesTo(name): | ||
488 | base_list.append(not_rev(name)) | ||
489 | if not base_list: | ||
490 | raise GitError('no base refs, cannot upload %s' % branch.name) | ||
491 | |||
492 | print >>sys.stderr, '' | ||
493 | _info("Uploading %s to %s:", branch.name, self.name) | ||
494 | try: | ||
495 | UploadBundle(project = self, | ||
496 | server = branch.remote.review, | ||
497 | email = self.UserEmail, | ||
498 | dest_project = branch.remote.projectname, | ||
499 | dest_branch = dest_branch, | ||
500 | src_branch = R_HEADS + branch.name, | ||
501 | bases = base_list, | ||
502 | people = people, | ||
503 | replace_changes = replace_changes) | ||
504 | except proto_client.ClientLoginError: | ||
505 | raise UploadError('Login failure') | ||
506 | except urllib2.HTTPError, e: | ||
507 | raise UploadError('HTTP error %d' % e.code) | ||
508 | |||
509 | elif branch.remote.ReviewProtocol == 'ssh': | ||
510 | if dest_branch.startswith(R_HEADS): | 483 | if dest_branch.startswith(R_HEADS): |
511 | dest_branch = dest_branch[len(R_HEADS):] | 484 | dest_branch = dest_branch[len(R_HEADS):] |
512 | 485 | ||