summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-01-26 10:55:39 -0800
committerShawn O. Pearce <sop@google.com>2009-01-26 10:55:39 -0800
commit370e3fa6660fa2eb675199104cde9e9d02063cfd (patch)
tree5ff9e8399be3a6ba7db48f20c00c86989634445f
parentb54a392c9a267a06058b663377282c9dcec6878e (diff)
downloadgit-repo-370e3fa6660fa2eb675199104cde9e9d02063cfd.tar.gz
Remove the protobuf based HTTP upload code path
Now that Gerrit2 has been released and the only supported upload protocol is direct git push over SSH we no longer need the large and complex protobuf client library, or the upload chunking logic in gerrit_upload.py. Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--Makefile10
-rw-r--r--codereview/__init__.py1
-rw-r--r--codereview/need_retry_pb2.py32
-rwxr-xr-xcodereview/proto_client.py380
-rw-r--r--codereview/review_pb2.py48
-rw-r--r--codereview/upload_bundle_pb2.py271
-rw-r--r--froofle/__init__.py0
-rw-r--r--froofle/protobuf/__init__.py0
-rw-r--r--froofle/protobuf/descriptor.py433
-rw-r--r--froofle/protobuf/descriptor_pb2.py950
-rw-r--r--froofle/protobuf/internal/__init__.py0
-rw-r--r--froofle/protobuf/internal/decoder.py209
-rw-r--r--froofle/protobuf/internal/encoder.py206
-rw-r--r--froofle/protobuf/internal/input_stream.py326
-rw-r--r--froofle/protobuf/internal/message_listener.py69
-rw-r--r--froofle/protobuf/internal/output_stream.py125
-rw-r--r--froofle/protobuf/internal/type_checkers.py268
-rw-r--r--froofle/protobuf/internal/wire_format.py236
-rw-r--r--froofle/protobuf/message.py246
-rw-r--r--froofle/protobuf/reflection.py1653
-rw-r--r--froofle/protobuf/service.py208
-rw-r--r--froofle/protobuf/service_reflection.py289
-rw-r--r--froofle/protobuf/text_format.py125
-rwxr-xr-xgerrit_upload.py174
-rw-r--r--project.py29
25 files changed, 1 insertions, 6287 deletions
diff --git a/Makefile b/Makefile
index 0184e08a..ea6aad5d 100644
--- a/Makefile
+++ b/Makefile
@@ -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
16GERRIT_SRC=../gerrit
17GERRIT_MODULES=codereview froofle
18
19all: 16all:
20 17
21clean: 18clean:
22 find . -name \*.pyc -type f | xargs rm -f 19 find . -name \*.pyc -type f | xargs rm -f
23
24update-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
4from froofle.protobuf import descriptor
5from froofle.protobuf import message
6from froofle.protobuf import reflection
7from froofle.protobuf import service
8from froofle.protobuf import service_reflection
9from 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
29class 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
15import base64
16import cookielib
17import getpass
18import logging
19import md5
20import os
21import random
22import socket
23import sys
24import time
25import urllib
26import urllib2
27import urlparse
28
29from froofle.protobuf.service import RpcChannel
30from froofle.protobuf.service import RpcController
31from need_retry_pb2 import RetryRequestLaterResponse;
32
33_cookie_jars = {}
34
35def _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
65class 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
74class 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
115class 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
4from froofle.protobuf import descriptor
5from froofle.protobuf import message
6from froofle.protobuf import reflection
7from froofle.protobuf import service
8from froofle.protobuf import service_reflection
9from froofle.protobuf import descriptor_pb2
10
11
12import 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
42class ReviewService(service.Service):
43 __metaclass__ = service_reflection.GeneratedServiceType
44 DESCRIPTOR = _REVIEWSERVICE
45class 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
4from froofle.protobuf import descriptor
5from froofle.protobuf import message
6from froofle.protobuf import reflection
7from froofle.protobuf import service
8from froofle.protobuf import service_reflection
9from 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
256class ReplacePatchSet(message.Message):
257 __metaclass__ = reflection.GeneratedProtocolMessageType
258 DESCRIPTOR = _REPLACEPATCHSET
259
260class UploadBundleRequest(message.Message):
261 __metaclass__ = reflection.GeneratedProtocolMessageType
262 DESCRIPTOR = _UPLOADBUNDLEREQUEST
263
264class UploadBundleResponse(message.Message):
265 __metaclass__ = reflection.GeneratedProtocolMessageType
266 DESCRIPTOR = _UPLOADBUNDLERESPONSE
267
268class 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
42file, in types that make this information accessible in Python.
43"""
44
45__author__ = 'robinson@google.com (Will Robinson)'
46
47class 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
81class 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...
179class 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
299class 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
339class 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
363class 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
395class 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
426def _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
4from froofle.protobuf import descriptor
5from froofle.protobuf import message
6from froofle.protobuf import reflection
7from froofle.protobuf import service
8from 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
879class FileDescriptorSet(message.Message):
880 __metaclass__ = reflection.GeneratedProtocolMessageType
881 DESCRIPTOR = _FILEDESCRIPTORSET
882
883class FileDescriptorProto(message.Message):
884 __metaclass__ = reflection.GeneratedProtocolMessageType
885 DESCRIPTOR = _FILEDESCRIPTORPROTO
886
887class 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
895class FieldDescriptorProto(message.Message):
896 __metaclass__ = reflection.GeneratedProtocolMessageType
897 DESCRIPTOR = _FIELDDESCRIPTORPROTO
898
899class EnumDescriptorProto(message.Message):
900 __metaclass__ = reflection.GeneratedProtocolMessageType
901 DESCRIPTOR = _ENUMDESCRIPTORPROTO
902
903class EnumValueDescriptorProto(message.Message):
904 __metaclass__ = reflection.GeneratedProtocolMessageType
905 DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO
906
907class ServiceDescriptorProto(message.Message):
908 __metaclass__ = reflection.GeneratedProtocolMessageType
909 DESCRIPTOR = _SERVICEDESCRIPTORPROTO
910
911class MethodDescriptorProto(message.Message):
912 __metaclass__ = reflection.GeneratedProtocolMessageType
913 DESCRIPTOR = _METHODDESCRIPTORPROTO
914
915class FileOptions(message.Message):
916 __metaclass__ = reflection.GeneratedProtocolMessageType
917 DESCRIPTOR = _FILEOPTIONS
918
919class MessageOptions(message.Message):
920 __metaclass__ = reflection.GeneratedProtocolMessageType
921 DESCRIPTOR = _MESSAGEOPTIONS
922
923class FieldOptions(message.Message):
924 __metaclass__ = reflection.GeneratedProtocolMessageType
925 DESCRIPTOR = _FIELDOPTIONS
926
927class EnumOptions(message.Message):
928 __metaclass__ = reflection.GeneratedProtocolMessageType
929 DESCRIPTOR = _ENUMOPTIONS
930
931class EnumValueOptions(message.Message):
932 __metaclass__ = reflection.GeneratedProtocolMessageType
933 DESCRIPTOR = _ENUMVALUEOPTIONS
934
935class ServiceOptions(message.Message):
936 __metaclass__ = reflection.GeneratedProtocolMessageType
937 DESCRIPTOR = _SERVICEOPTIONS
938
939class MethodOptions(message.Message):
940 __metaclass__ = reflection.GeneratedProtocolMessageType
941 DESCRIPTOR = _METHODOPTIONS
942
943class 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
33Contains the logic for decoding every logical protocol field type
34from one of the 5 physical wire types.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from froofle.protobuf import message
41from froofle.protobuf.internal import input_stream
42from 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
51class 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
33Contains the logic for encoding every logical protocol field type
34into one of the 5 physical wire types.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from froofle.protobuf import message
41from froofle.protobuf.internal import wire_format
42from 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
50class 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
33All protocol buffer deserialization can be expressed in terms of
34the InputStream primitives provided here.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from array import array
41from froofle.protobuf import message
42from 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
50class 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
228class 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
318try:
319 buffer("")
320 InputStream = InputStreamBuffer
321except NotImplementedError:
322 # Google App Engine: dev_appserver.py
323 InputStream = InputStreamArray
324except 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
32state transitions on Message objects.
33
34Also defines a null implementation of this interface.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39
40class 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
61class 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
33All protocol buffer serialization can be expressed in terms of
34the OutputStream primitives provided here.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import array
40import struct
41from froofle.protobuf import message
42from 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
51class 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
33This module defines type checking utilities in the forms of dictionaries:
34
35VALUE_CHECKERS: A dictionary of field types and a value validation object.
36TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
37 function.
38TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
39 function.
40FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
41 coresponding wire types.
42TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
43 function.
44"""
45
46__author__ = 'robinson@google.com (Will Robinson)'
47
48from froofle.protobuf.internal import decoder
49from froofle.protobuf.internal import encoder
50from froofle.protobuf.internal import wire_format
51from froofle.protobuf import descriptor
52
53_FieldDescriptor = descriptor.FieldDescriptor
54
55
56def 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
78class 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.
96class 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
109class 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
129class 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
136class Uint32ValueChecker(IntValueChecker):
137 _MIN = 0
138 _MAX = (1 << 32) - 1
139
140
141class Int64ValueChecker(IntValueChecker):
142 _MIN = -(1 << 63)
143 _MAX = (1 << 63) - 1
144
145
146class 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".
171TYPE_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
197TYPE_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.
220FIELD_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
251TYPE_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
35import struct
36from froofle.protobuf import message
37
38
39TAG_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.
46WIRETYPE_VARINT = 0
47WIRETYPE_FIXED64 = 1
48WIRETYPE_LENGTH_DELIMITED = 2
49WIRETYPE_START_GROUP = 3
50WIRETYPE_END_GROUP = 4
51WIRETYPE_FIXED32 = 5
52_WIRETYPE_MAX = 5
53
54
55# Bounds for various integer types.
56INT32_MAX = int((1 << 31) - 1)
57INT32_MIN = int(-(1 << 31))
58UINT32_MAX = (1 << 32) - 1
59
60INT64_MAX = (1 << 63) - 1
61INT64_MIN = -(1 << 63)
62UINT64_MAX = (1 << 64) - 1
63
64# "struct" format strings that will encode/decode the specified formats.
65FORMAT_UINT32_LITTLE_ENDIAN = '<I'
66FORMAT_UINT64_LITTLE_ENDIAN = '<Q'
67
68
69# We'll have to provide alternate implementations of AppendLittleEndian*() on
70# any architectures where these checks fail.
71if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4:
72 raise AssertionError('Format "I" is not a 32-bit number.')
73if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8:
74 raise AssertionError('Format "Q" is not a 64-bit number.')
75
76
77def 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
90def 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
97def 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
107def 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
119def Int32ByteSize(field_number, int32):
120 return Int64ByteSize(field_number, int32)
121
122
123def Int64ByteSize(field_number, int64):
124 # Have to convert to uint before calling UInt64ByteSize().
125 return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
126
127
128def UInt32ByteSize(field_number, uint32):
129 return UInt64ByteSize(field_number, uint32)
130
131
132def UInt64ByteSize(field_number, uint64):
133 return _TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
134
135
136def SInt32ByteSize(field_number, int32):
137 return UInt32ByteSize(field_number, ZigZagEncode(int32))
138
139
140def SInt64ByteSize(field_number, int64):
141 return UInt64ByteSize(field_number, ZigZagEncode(int64))
142
143
144def Fixed32ByteSize(field_number, fixed32):
145 return _TagByteSize(field_number) + 4
146
147
148def Fixed64ByteSize(field_number, fixed64):
149 return _TagByteSize(field_number) + 8
150
151
152def SFixed32ByteSize(field_number, sfixed32):
153 return _TagByteSize(field_number) + 4
154
155
156def SFixed64ByteSize(field_number, sfixed64):
157 return _TagByteSize(field_number) + 8
158
159
160def FloatByteSize(field_number, flt):
161 return _TagByteSize(field_number) + 4
162
163
164def DoubleByteSize(field_number, double):
165 return _TagByteSize(field_number) + 8
166
167
168def BoolByteSize(field_number, b):
169 return _TagByteSize(field_number) + 1
170
171
172def EnumByteSize(field_number, enum):
173 return UInt32ByteSize(field_number, enum)
174
175
176def StringByteSize(field_number, string):
177 return BytesByteSize(field_number, string.encode('utf-8'))
178
179
180def BytesByteSize(field_number, b):
181 return (_TagByteSize(field_number)
182 + _VarUInt64ByteSizeNoTag(len(b))
183 + len(b))
184
185
186def GroupByteSize(field_number, message):
187 return (2 * _TagByteSize(field_number) # START and END group.
188 + message.ByteSize())
189
190
191def MessageByteSize(field_number, message):
192 return (_TagByteSize(field_number)
193 + _VarUInt64ByteSizeNoTag(message.ByteSize())
194 + message.ByteSize())
195
196
197def 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
220def _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
226def _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
39from froofle.protobuf import text_format
40
41class Error(Exception): pass
42class DecodeError(Error): pass
43class EncodeError(Error): pass
44
45
46class 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
37protocol message classes from Descriptor objects at runtime.
38
39Recall that a metaclass is the "type" of a class.
40(A class is to a metaclass what an instance is to a class.)
41
42In this case, we use the GeneratedProtocolMessageType metaclass
43to inject all the useful functionality into the classes
44output by the protocol compiler at compile-time.
45
46The upshot of all this is that the real implementation
47details for ALL pure-Python protocol buffers are *here in
48this file*.
49"""
50
51__author__ = 'robinson@google.com (Will Robinson)'
52
53import heapq
54import threading
55import weakref
56# We use "as" to avoid name collisions with variables.
57from froofle.protobuf.internal import decoder
58from froofle.protobuf.internal import encoder
59from froofle.protobuf.internal import message_listener as message_listener_mod
60from froofle.protobuf.internal import type_checkers
61from froofle.protobuf.internal import wire_format
62from froofle.protobuf import descriptor as descriptor_mod
63from froofle.protobuf import message as message_mod
64
65_FieldDescriptor = descriptor_mod.FieldDescriptor
66
67
68class 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
166def _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
187def _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
198def _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
210def _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
230def _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
237def _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
249def _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
288def _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
312def _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
318def _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
340def _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
373def _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
408def _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
456def _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
464def _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
513def _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
523def _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
551def _AddClearExtensionMethod(cls):
552 """Helper for _AddMessageMethods()."""
553 def ClearExtension(self, extension_handle):
554 self.Extensions._ClearExtension(extension_handle)
555 cls.ClearExtension = ClearExtension
556
557
558def _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
572def _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
579def _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
608def _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
618def _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
638def _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
695def _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
711def _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
732def _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
764def _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
776def _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
796def _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
804def _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
826def _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
837def _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
862def _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
878def _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
917def _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
1010def _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
1037def _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
1061def _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
1097def _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
1117def _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
1132def _AddIsInitializedMethod(cls):
1133 """Adds the IsInitialized method to the protocol message class."""
1134 cls.IsInitialized = _InternalIsInitialized
1135
1136
1137def _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
1170def _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
1178def _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
1196def _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
1219class _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()?
1275class _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?
1341class _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?
1412class _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
33This module declares the abstract interfaces underlying proto2 RPC
34services. These are intented to be independent of any particular RPC
35implementation, so that proto2 services can be used on top of a variety
36of implementations.
37"""
38
39__author__ = 'petar@google.com (Petar Petrov)'
40
41
42class 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
100class 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
183class 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
32classes from ServiceDescriptor objects at runtime.
33
34The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to
35inject all useful functionality into the classes output by the protocol
36compiler at compile-time.
37"""
38
39__author__ = 'petar@google.com (Petar Petrov)'
40
41
42class 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
84class 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
114class _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
237class _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
35import cStringIO
36
37from froofle.protobuf import descriptor
38
39__all__ = [ 'MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue' ]
40
41def MessageToString(message):
42 out = cStringIO.StringIO()
43 PrintMessage(message, out)
44 result = out.getvalue()
45 out.close()
46 return result
47
48def 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
56def 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
85def 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.
112def _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
16import getpass
17import os
18import sys
19from tempfile import mkstemp
20
21from codereview.proto_client import HttpRpc, Proxy
22from codereview.review_pb2 import ReviewService_Stub
23from codereview.upload_bundle_pb2 import *
24from git_command import GitCommand
25from error import UploadError
26
27try:
28 import readline
29except ImportError:
30 pass
31
32MAX_SEGMENT_SIZE = 1020 * 1024
33
34def _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
71def 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)
diff --git a/project.py b/project.py
index 5d036c35..eebe96d5 100644
--- a/project.py
+++ b/project.py
@@ -24,10 +24,8 @@ import urllib2
24from color import Coloring 24from color import Coloring
25from git_command import GitCommand 25from git_command import GitCommand
26from git_config import GitConfig, IsId 26from git_config import GitConfig, IsId
27from gerrit_upload import UploadBundle
28from error import GitError, ImportError, UploadError 27from error import GitError, ImportError, UploadError
29from remote import Remote 28from remote import Remote
30from codereview import proto_client
31 29
32HEAD = 'HEAD' 30HEAD = 'HEAD'
33R_HEADS = 'refs/heads/' 31R_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