diff --git a/code/dbapi.py b/code/dbapi.py
index 054cd0a..bf5d96a 100644
--- a/code/dbapi.py
+++ b/code/dbapi.py
@@ -1,4 +1,6 @@
+# -*- coding: utf-8 -*-
import MySQLdb,json
+import thread,time
#in init function please change the config to fit your own requirement
#fetchone(): return type: None/dict
@@ -10,9 +12,12 @@ def __init__(self):
self.host="localhost"
self.user="comhelp"
self.passwd="20140629"
+ #self.user="root"
+ #self.passwd="root"
self.dbname="community"
self.charset="utf8"
self.db=MySQLdb.connect(host=self.host,user=self.user,passwd=self.passwd,db=self.dbname,charset=self.charset)
+ thread.start_new_thread(self.setDailyTask, ())
def getUserByUserId(self,userid):
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
@@ -32,6 +37,101 @@ def getUserByUserName(self,username):
cursor.close()
return result
+ def getHelperInfoByEid(self,eid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select user.name as username,user.id as uid from helper,user where helper.eid=%s and helper.usrid = user.id"
+ param=(eid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchall()
+ cursor.close()
+ return result
+
+ def updateUserstate(self,uid,state):
+ cursor = self.db.cursor()
+ sql = "update user set state = %s where id = %s"
+ param =(state,uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ def updateUserCredit(self,uid,credit):
+ cursor = self.db.cursor()
+ sql = "update info set credit = %s where id = %s"
+ param = (credit,uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+
+ def updateUseLBS(self,latitude,longitude,uid):
+ cursor = self.db.cursor()
+ sql = "update info set latitude = %s , longitude = %s where id = %s"
+ param =(latitude,longitude,uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ #get user userfull info in user+info
+ #pre con: user exist
+ #after: return a dict result include all info of user
+ def getUserAllinfobyName(self,name):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ uid = self.getUserByUserName(name)['id']
+ return self.getUsermessegeByUserId(uid)
+
+ #get user all info in user+info
+ #pre con: user exist
+ #after: return a dict result include all info of user
+ def getUserInfobyName(self,name):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from user,info where user.name = %s and user.id = info.id"
+ param = (name,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def getUserInfobyUid(self,uid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from user,info where user.id = %s and user.id = info.id"
+ param = (uid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def CheckRelationbyId(self,userid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from relation where usrid=%s"
+ param=(userid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchall()
+ cursor.close()
+ return result
+
+ def getUsermessegeByUserId(self,userid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select user.id,user.name,info.name as realname,info.sex,info.age,info.address,info.illness,info.credit,info.score,phone from user,info where user.id=%s and info.id=%s"
+ param=(userid,userid)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def getUserByEid(self,eid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select cid,user.id as uid from user,event where event.id= %s and event.usrid=user.id"
+ param=(eid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
def getEventByEventId(self,eventid):
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
sql="select * from event where id=%s"
@@ -41,6 +141,19 @@ def getEventByEventId(self,eventid):
cursor.close()
return result
+ def getEventandUserByEventId(self,eventid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="""select user.name as username,user.id as userid,content,starttime as time,event.kind as kind,event.id as eventid, event.latitude as latitude,event.longitude as longitude,Video as video, audio from event,user
+ where event.id=%s and user.id = event.usrid"""
+ param=(eventid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ result['time'] = result['time'].strftime('%Y-%m-%d %H:%M:%S')
+ result['longitude'] = float(result['longitude'])
+ result['latitude'] = float(result['latitude'])
+ cursor.close()
+ return result
+
def getEventsByUserId(self,userid):
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
sql="select * from event where usrid=%s"
@@ -54,7 +167,439 @@ def getEventsByUserName(self,username):
user=self.getUserByUserName(username)
if(not user):
return []
- return self.getEventsByUserId(user["userid"])
+ return self.getEventsByUserId(user["id"])
+
+ def getSupportBySid(self,sid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from support where id = %s"
+ param=(sid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ #get supports by uid
+ def getSupportsbyUid(self,uid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select user.name,support.eid,support.content,support.time from support,user where usrid = user.id and usrid = %s"
+ param=(uid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchall()
+ cursor.close()
+ return list(result)
+
+ #get supports by username
+ def getSupportsbyUsername(self,username):
+ user=self.getUserByUserName(username)
+ if(not user):
+ return []
+ return self.getSupportsbyUid(user["id"])
+
+ #insert follow uid->eid
+ def insertFollow(self,uid,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ cursor.execute("select now()")
+ currentTime=cursor.fetchone()
+ sql = "insert into follow(eid,usrid,time) values(%s,%s,%s)"
+ param = (eid,uid,currentTime['now()'])
+ state = 1
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ state = 1
+ except:
+ self.db.rollback()
+ state = 0
+ cursor.close()
+ return state
+
+ #delect follow uid->eid
+ def delectFollow(self,uid,eid):
+ cursor = self.db.cursor()
+ sql = "delete from follow where eid = %s and usrid = %s"
+ param = (eid,uid)
+ state = 1
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ state = 1
+ except:
+ self.db.rollback()
+ state = 0
+ cursor.close()
+ return state
+
+ #get follow by uid,eid
+ #if no recode,rerun None;else return dir
+ def getFollow(self,uid,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from follow where eid = %s and usrid = %s"
+ param = (eid,uid)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def getFollowerCidByEid(self,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select user.cid from follow,user where eid = %s and user.id = follow.usrid"
+ param = (eid,)
+ cursor.execute(sql,param)
+ result = []
+ for row in cursor.fetchall():
+ result.append(row['cid'])
+ cursor.close()
+ return result
+
+ def getFollowsByEventId(self,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select count(*) as count from follow where eid = %s"
+ param = (eid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+
+ def getHelpersCidbyEid(self,eid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select cid from helper,user where eid = %s and helper.usrid = user.id"
+ param=(eid,)
+ cursor.execute(sql,param)
+ result = []
+ for row in cursor.fetchall():
+ result.append(row['cid'])
+ cursor.close()
+ return result
+
+ def getRelativesCidbyUid(self,uid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select user.cid from relation,user where usrid = %s and relation.cid = user.id"
+ param=(uid,)
+ cursor.execute(sql,param)
+ result = []
+ for row in cursor.fetchall():
+ result.append(row['cid'])
+ cursor.close()
+ return result
+
+ def getRelativesIdbyUid(self,uid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select cid as id from relation where usrid = %s"
+ param=(uid,)
+ cursor.execute(sql,param)
+ result = cursor.fetchall()
+ cursor.close()
+ return list(result)
+
+ def getHelpersIdbyUid(self,uid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select DISTINCT helper.usrid as id from event,helper where event.usrid = %s and event.id = helper.eid"
+ param=(uid,)
+ cursor.execute(sql,param)
+ result = cursor.fetchall()
+ cursor.close()
+ return list(result)
+
+ #check if cardid exist
+ #exist return dict
+ #not exist return none
+ def getInfoBycardid(self,cardid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from info where cardid=%s"
+ param=(cardid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ #register a new user
+ #pre condiction:no user.name,info.cardid duplicate
+ #after : insert new user,new info
+ def register(self,content):
+ cursor = self.db.cursor()
+ sql = "insert into user(name,kind,password) values(%s,%s,%s)"
+ param = (content["username"],content["kind"],content["password"])
+ cursor.execute(sql,param)
+ self.db.commit()
+
+ cursor.execute('SELECT LAST_INSERT_ID()')
+ result=cursor.fetchone()
+ print result[0]
+
+ sql = "insert into info(id,cardid,name,sex,age,illness,score,phone,vocation) values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"
+ param = (result[0],content["cardid"],content["realname"],content["sex"],content["age"],content["illness"],0,content["phone"],content["vocation"])
+ cursor.execute(sql,param)
+ self.db.commit()
+
+ cursor.close()
+ return result[0]
+
+ def getRelationByUserId(self, u_id, r_id):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="SELECT * FROM relation WHERE usrid = '" + u_id + "' AND cid = '" + r_id + "'"
+ cursor.execute(sql)
+ row = int(cursor.rowcount)
+ cursor.close()
+ return row
+
+ #update user cid by uid
+ def UpdateCidByuid(self,cid,uid):
+ cursor = self.db.cursor()
+ sql ="update user set cid = NULl where cid = %s"
+ param = (cid,)
+ cursor.execute(sql,param)
+ self.db.commit()
+
+ sql = "update user set cid = %s where id = %s"
+ param = (cid,uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ def UpdateInfotimebyUid(self,uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ cursor.execute("select now()")
+ currentTime=cursor.fetchone()
+ sql ="update info set time = %s where id = %s"
+ print currentTime['now()']
+ param = (currentTime['now()'],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+ def updateUserbetagama(self,uid,beta,gama):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql ="update info set beta = %s, gama = %s where id = %s"
+ param = (beta,gama,uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+
+ #get all relativeName by user.id
+ #return a list contain all relations(including uid)
+ def getAllRelativeNamebyUid(self,uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from relation where usrid = %s and kind = %s"
+ param = (uid,1)
+ rlist = []
+ rlist.append(uid)
+ cursor.execute(sql,param)
+ for row in cursor.fetchall():
+ rlist.append(row["cid"])
+ return rlist
+
+ # change a event sate to 1
+ #in order to end a event
+ def changeEventState(self,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ cursor.execute("select now()")
+ currentTime=cursor.fetchone()
+ sql ="update event set state= %s ,endtime = %s where id = %s"
+ param = (1,currentTime['now()'],eid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return currentTime['now()']
+
+ #cancle a user by user(id)
+ #pre condiction: uid exist
+ #after:delete all record of this user
+ def cancelUser(self,uid):
+ cursor = self.db.cursor()
+ sql = "delete from user where id = %s"
+ param = (uid,)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ #get all events around user(latitude,longitude) inside distance
+ #pre con:user(latitude,longitude) exist,distance >=0
+ #after:return a list contain event info or []
+ def getEventAround(self,lon,lat,distance):
+ cursor = self.db. cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ #sql = "select round(6378.138*2*asin(sqrt(pow(sin( (event.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(event.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (event.longitude*pi()/180-(%s)*pi()/180)/2),2)))) from event"
+ #param = (lat,lat,lon)
+ sql = """select event.id,user.name,event.kind,event.content,event.starttime,video,audio from event,user where
+ exists(select id from event where event.latitude <= (%s+1) and event.latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and event.usrid = user.id
+ and event.state = 0
+ and round(6378.138*2*asin(sqrt(pow(sin( (event.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(event.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (event.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s
+ ORDER BY starttime DESC limit 15"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ cursor.execute(sql,param)
+ result = []
+ for row in cursor.fetchall():
+ row['starttime'] = row['starttime'].strftime('%Y-%m-%d %H:%M:%S')
+ result.append(row)
+ cursor.close()
+ return result
+
+ #get all user(cid) around latitude,longitude inside distance(use for push)
+ #pre condiction:lon,lat exist,distance>=0
+ #after :return a list coantain user.cid or []
+ def getUserCidAround(self,lon,lat,distance):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = """select user.cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.state = 1
+ and user.id = info.id
+ and round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ cursor.execute(sql,param)
+ result = []
+ for row in cursor.fetchall():
+ result.append(row['cid'])
+ cursor.close()
+ return result
+
+ def getUserAround(self,lon,lat,distance):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = """select user.name as name from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ cursor.execute(sql,param)
+ sqlre = cursor.fetchall()
+ cursor.close
+ result = []
+ if(sqlre):
+ for row in sqlre:
+ info = {}
+ info['username'] = row['name']
+ result.append(info)
+ data={'state':1,'users':result}
+ else:
+ data={'state':0}#the user not exist,return state 0
+ #result=json.dumps(data)
+ return data
+
+ def getUserAroundbykind(self,lon,lat,distance,kind):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ if(kind == 1):
+ sql = """select user.id as id,user.name as name,info.credit as credit ,user.cid as cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and (age>=20 and age <=40)
+ and round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ elif(kind == 2):
+ sql ="""select user.id as id,user.name as name,info.credit as credit ,user.cid as cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and (age>=20 and age <=50)
+ and round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ else:
+ sql = """select user.id as id,user.name as name,info.credit as credit ,user.cid as cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) < %s"""
+ param = (lat,lat,lon,lon,lat,lat,lon,distance)
+ cursor.execute(sql,param)
+ sqlre = cursor.fetchall()
+ return list(sqlre)
+
+ def getAroundbyvocationOrKind(self,lon,lat,vocation,u_kind,vocation_limit,u_limit):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = """(select user.cid as cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and (vocation = %s)
+ order by round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) asc limit %s)
+ UNION
+ (select user.cid as cid from user,info where
+ exists(select id from info where latitude <= (%s+1) and latitude >= (%s-1) and longitude <= (%s+1) and longitude>=(%s-1))
+ and user.id = info.id
+ and (kind = %s)
+ order by round(6378.138*2*asin(sqrt(pow(sin( (info.latitude*pi()/180-(%s)*pi()/180)/2),2)+cos(info.latitude*pi()/180)*cos((%s)*pi()/180)* pow(sin( (info.longitude*pi()/180-(%s)*pi()/180)/2),2)))) asc limit %s)"""
+ param = (lat,lat,lon,lon,vocation,lat,lat,lon,vocation_limit,lat,lat,lon,lon,u_kind,lat,lat,lon,u_limit)
+ cursor.execute(sql,param)
+ cursor.close
+ result = []
+ for row in cursor.fetchall():
+ result.append(row['cid'])
+ cursor.close()
+ return result
+
+ #update user info by username,sex,age,phone,address,illness
+ #pre cond:uid exist
+ #after: update user info for what it pass
+ def updateUserinfo(self,uid,message):
+ cursor = self.db.cursor()
+ result = []
+ if("realname" in message):
+ sql = "update info set name = %s where id = %s"
+ param = (message["realname"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error username"}
+ result.append({"state":1,"desc":"update username success"})
+ if("sex" in message):
+ sql = "update info set sex = %s where id = %s"
+ param = (message["sex"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error sex"}
+ result.append({"state":1,"desc":"update sex success"})
+ if("age" in message):
+ sql = "update info set age = %s where id = %s"
+ param = (message["age"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error age"}
+ result.append({"state":1,"desc":"update age success"})
+ if("phone" in message):
+ sql = "update info set phone = %s where id = %s"
+ param = (message["phone"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error age"}
+ result.append({"state":1,"desc":"update age success"})
+ if("address" in message):
+ sql = "update info set address = %s where id = %s"
+ param = (message["address"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error address"}
+ result.append({"state":1,"desc":"update address success"})
+ if("illness" in message):
+ sql = "update info set illness = %s where id = %s"
+ param = (message["illness"],uid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ return {"state":2,"desc":"db access error illness"}
+ result.append({"state":1,"desc":"update illness success"})
+ cursor.close()
+ return result
'''Yeqin Zheng, 09/07/2014'''
def getRelationByUsername(self, u_name, r_name):
@@ -77,43 +622,573 @@ def deleteRelationByUsername(self, u_name, r_name):
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
sql="DELETE FROM relation WHERE usrid = '" + u_id + "' AND cid = '" + r_id + "'"
cursor.execute(sql)
+ self.db.commit()
cursor.close()
- def addRelationByUsername(self, u_name, r_name):
- result = self.getUserByUserName(u_name)
- u_id = str(result["id"])
- result = self.getUserByUserName(r_name)
- r_id = str(result["id"])
+ def addRelationByUid(self, u_id, r_id,kind):
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
- sql="INSERT INTO relation (usrid, cid, kind) VALUES ('" + u_id + "', '" + r_id + "', '1')"
- cursor.execute(sql)
+ sql="INSERT INTO relation(usrid, cid, kind) VALUES(%s,%s,%s)"
+ param=(u_id,r_id,kind)
+ cursor.execute(sql,param)
+ self.db.commit()
+ sql="INSERT INTO relation(usrid, cid, kind) VALUES(%s,%s,%s)"
+ param=(r_id,u_id,kind)
+ cursor.execute(sql,param)
+ self.db.commit()
cursor.close()
- def addtempRelationByUsername(self, u_name, r_name):
+
+ def addtempRelationByUsername(self, u_name, r_name,kind,info):
result = self.getUserByUserName(u_name)
u_id = str(result["id"])
result = self.getUserByUserName(r_name)
r_id = str(result["id"])
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
- sql="INSERT INTO relation (usrid, cid, kind) VALUES ('" + u_id + "', '" + r_id + "', '1')"
- cursor.execute(sql)
+ sql="INSERT INTO temprelation (uid, cid, kind,info) VALUES(%s,%s,%s,%s)"
+ param=(u_id,r_id,kind,info)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+
+ def deletetemprelation(self,uid,cid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="delete from temprelation where uid = %s and cid =%s"
+ param=(uid,cid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+
+ def deletetemprelationwithkind(self,uid,cid,kind):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="delete from temprelation where uid = %s and cid =%s and kind = %s"
+ param=(uid,cid,kind)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
cursor.close()
+ return
+
+ def gettemprelationbyCid(self,cid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from temprelation where cid =%s"
+ param=(cid,)
+ cursor.execute(sql,param)
+ result = cursor.fetchall()
+ return list(result)
def addaidhelper(self, u_name, e_id):
result = self.getUserByUserName(u_name)
u_id = str(result["id"])
result = self.getEventByEventId(e_id)
- if result["state"] == 0:
- return "0"
- else :
+ if(self.checkifUseraddHelper(u_id,e_id) is not None):
+ print "already add in,do not need add agagin"
+ return "2"
+ if result["state"] == 1:
+ print "current has benn end"
+ return "3"
+ else:
cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
sql="INSERT INTO helper (eid, usrid) VALUES ('" + e_id + "', '" + u_id + "')"
cursor.execute(sql)
+ self.db.commit()
cursor.close()
+ print "user " +u_name +" add in "+ e_id
return "1"
+ def checkifUseraddHelper(self,userid,eventid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from helper where eid=%s and usrid = %s"
+ param=(eventid,userid)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ print result
+ return result
+
+ def deleteHelperbyUidEid(self,uid,eid):
+ cursor=self.db.cursor()
+ sql="delete from helper where eid = %s and usrid = %s"
+ param=(eid,uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+
+ #Anton Zhong
+ def getUserIdByUserName(self,username):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select id from user where name=%s"
+ param=(username,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def addEventByUserName(self,username,message):
+ usrid=self.getUserIdByUserName(username)
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ if(not usrid):
+ return {"state":2,"errorDesc":"No Such User: "+username}
+ else:
+ if(not("kind" in message and "content" in message)):
+ return {"state":3,"errorDesc":"Messge Incomplete"}
+ else:
+ cursor.execute("select now()")
+ currentTime=cursor.fetchone()
+ #sql = "select * from event where usrid = %s and kind = %s and latitude = %s and longitude = %s and TIMESTAMPDIFF(MINUTE,%s,starttime)<= 10"
+ #param = (usrid["id"],message["kind"],message['latitude'],message['longitude'],currentTime['now()'])
+ #cursor.execute(sql,param)
+ #if(cursor.fetchall()):
+ if(False):
+ return {"state":4,"errorDesc":"cannnot send the same message in 10 minute"}
+ sql="insert into event (usrid,kind,state,content,starttime,latitude,longitude) values (%s,%s,%s,%s,%s,%s,%s)"
+ param=(usrid["id"],message["kind"],0,message["content"],currentTime['now()'],message['latitude'],message['longitude'])
+ cursor.execute(sql,param)
+ self.db.commit()
+
+ cursor.execute("select last_insert_id()")
+ eid = cursor.fetchone()["last_insert_id()"]
+ if(message['videosign'] =="1" and message['audiosign'] =="1"):
+ self.UpdateEventVideoAndAudio(eid)
+ elif(message['videosign'] =="1" and message['audiosign'] =="0"):
+ self.UpdateEventVideo(eid)
+ elif(message['videosign'] =="0" and message['audiosign'] =="1"):
+ self.UpdateEventAudio(eid)
+ return {"state":1,"errorDesc":"","eventid":eid}
+ cursor.close()
+
+ def UpdateEventVideoAndAudio(self,eid):
+ cursor = self.db.cursor()
+ sql = "update event set video = %s,audio = %s where id = %s"
+ param = ('http://114.215.133.61:8080/static/Video/'+str(eid)+'/'+str(eid)+'.3gp','http://114.215.133.61:8080/static/Audio/'+str(eid)+'/'+str(eid)+'.amr',eid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ def UpdateEventVideo(self,eid):
+ cursor = self.db.cursor()
+ sql = "update event set video = %s where id = %s"
+ param = ('http://114.215.133.61:8080/static/Video/'+str(eid)+'/'+str(eid)+'.3gp',eid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+
+ def UpdateEventAudio(self,eid):
+ cursor = self.db.cursor()
+ sql = "update event set audio = %s where id = %s"
+ param = ('http://114.215.133.61:8080/static/Audio/'+str(eid)+'/'+str(eid)+'.amr',eid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ return
+ #07/09
+
+ #seach user by sex,age,kind and return the row of table user
+ # it has 8 options
+ def searchUserbySexAgeKind(self,content):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ if('sex' in content):
+ if('fromage' in content):
+ if('kind' in content):
+ sql="select user.id from user,info where info.sex=%s and info.age>=%s and info.age<=%s and user.kind=%s and user.id = info.id"
+ param=(content['sex'],content['fromage'],content['endage'],content['kind'])
+ else:
+ sql="select user.id from user,info where info.sex=%s and info.age>=%s and info.age<=%s and user.id = info.id"
+ param=(content['sex'],content['fromage'],content['endage'])
+ else:
+ if('kind' in content):
+ sql="select user.id from user,info where info.sex=%s and user.kind=%s and user.id = info.id"
+ param=(content['sex'],content['kind'])
+ else:
+ sql="select info.id from info,user where info.sex=%s and user.id = info.id"
+ param=(content['sex'],)
+ else:
+ if('fromage' in content):
+ if('kind' in content):
+ sql="select user.id from user,info where info.age>=%s and info.age<=%s and user.kind=%s and user.id = info.id"
+ param=(content['fromage'],content['endage'],content['kind'])
+ else:
+ sql="select user.id from user,info where info.age>=%s and info.age<=%s and user.id = info.id"
+ param=(content['fromage'],content['endage'])
+ else:
+ if('kind' in content):
+ sql="select user.id from user,info where user.kind=%s and user.id = info.id"
+ param=(content['kind'],)
+ else:
+ data=[{'state':0}]#input is null return state 0
+ result=json.dumps(data)
+ return result
+ cursor.execute(sql,param)
+ result1=cursor.fetchall()
+ cursor.close()
+ if(result1):
+ userlist=[]
+ for x in result1:
+ info = {}
+ info['username'] = self.getUserByUserId(x['id'])['name']
+ userlist.append(info)
+ data={'state':1,'users':userlist}#return the user table successly
+ else:
+ data={'state':0}#the user not exist,return state 0
+ return data
+
+ #update the password by userid and userpassword
+ def UpdatePassword(self,content):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ if(content['passwd']):
+ sql="update user set passwd=%s where id=%s"
+ param=(content['passwd'],content['id'])
+ cursor.execute(sql,param)
+ self.db.commit()
+ data=[{'state':1}]#update success return state 1
+ result=json.dumps(data)
+ return result
+
+ else:
+ data=[{'state':0}]#input is null return state 0
+ result=json.dumps(data)
+ return result
+ cursor.close()
+
+
+ #Anton Zhong
+ def getHelperByEventIdAndUserName(self,eid,username):
+ usrid=self.getUserIdByUserName(username)
+ #No such user return none
+ if(not usrid):
+ return None
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from helper where eid=%s and usrid=%s"
+ param=(eid,usrid["id"])
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ cursor.close()
+ return result
+
+ def checkHelperByEventIdAndUserName(self,eid,username):
+ usrid=self.getUserIdByUserName(username)
+ if(not usrid):
+ return False
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select usrid from helper where eid=%s"
+ param=(eid,)
+ cursor.execute(sql,param)
+ result=cursor.fetchone()
+ if(not result):
+ return False
+ return True
+
+ def addSupportByEventIdAndUserName(self,eid,username,message):
+ #if(not self.checkHelperByEventIdAndUserName(eid,username)):
+ # return {"errorCode":403,"errorDesc":"No Such Helper"+str(username)+" in event "+str(eid)}
+ if(not ("content" in message) ):
+ return {"errorCode":403,"errorDesc":"Messge Incomplete"}
+ else:
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ cursor.execute("select now()")
+ currentTime=cursor.fetchone()
+ sql="insert into support (eid,usrid,content,time) values (%s,%s,%s,%s)"
+ param=(eid,self.getUserIdByUserName(username)["id"],message["content"],currentTime['now()'])
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.execute("select last_insert_id()")
+ result=cursor.fetchone()
+ cursor.close()
+ return {"errorCode":200,"errorDesc":"","supportid":result["last_insert_id()"]}
+
+ def setCreditByEventIdAndUserName(self,eid,username,credit):
+ if(not self.checkHelperByEventIdAndUserName(eid,username)):
+ return {"errorCode":403,"errorDesc":"No Such Helper "+str(username)+" in event "+str(eid)}
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="update helper set credit = %s where eid=%s and usrid=%s"
+ usrid=self.getUserIdByUserName(username)
+ param=(credit,eid,usrid["id"])
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+ #self.updateUserCreditScore(eid,usrid["id"],credit)
+ return {"errorCode":200,"errorDesc":""}
+ #07/10
+
+ def getSupportsByEventId(self,eid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from support where eid=%s ORDER BY time DESC"
+ param=(eid,)
+ cursor.execute(sql,param)
+ result=[]
+ for item in cursor.fetchall():
+ item['time'] = item['time'].strftime('%Y-%m-%d %H:%M:%S')
+ result.append(item)
+ return result
+
+ #get record from previousEvent
+ #after:return None or dict
+ def getpreviousEvent(self,askid,helperid):
+ cursor=self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql="select * from previousEvent where askid=%s and helperid = %s"
+ param=(askid,helperid)
+ cursor.execute(sql,param)
+ result = cursor.fetchone()
+ return result
+
+ #insert new record into previousEvent
+ #after:the table insert a new record
+ def insertpreviousEvent(self,askid,helperid,credit,eventstarttime):
+ cursor = self.db.cursor()
+ sql = "insert into previousEvent(askid,helperid,time,credit) values(%s,%s,%s,%s)"
+ param = (askid,helperid,eventstarttime,credit)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+
+ #update the record in previousEvent
+ #after:update the record of (askid,helpid)
+ def updatepreviousEvent(self,askid,helperid,credit,eventstarttime):
+ cursor = self.db.cursor()
+ sql = "update previousEvent set credit = %s, time = %s where askid = %s and helperid = %s"
+ param = (credit,eventstarttime,askid,helperid)
+ try:
+ cursor.execute(sql,param)
+ self.db.commit()
+ except:
+ self.db.rollback()
+ cursor.close()
+ return
+
+ def insertAuth(self, uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "insert into auth(id, email_state, phone_state) values(%s, 'unauth', 'unauth')"
+ param = (uid,)
+ succeed = True
+ try:
+ cursor.execute(sql, param)
+ self.db.commit()
+ except Exception as e:
+ succeed = False
+ print(e)
+ finally:
+ cursor.close()
+ return succeed
+
+ def getAuth(self, uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from auth where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ cursor.close()
+ return result
+
+ def updateAuthState(self, uid, kind, newState):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "update auth set %s_state = '%s' where id = %%s" % (kind, newState)
+ param = (uid,)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ def updateAuthData(self, uid, kind, value):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "update auth set %s = %%s where id = %%s" % kind
+ param = (value, uid)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ # if in limit, return True.
+ def checkAuthCnt(self, uid, kind, limits):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from auth_cnt where id = %%s and kind = \"%s\"" % kind
+ param = (uid,)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ sql = "insert into auth_cnt(id, kind, cnt) values(%%s, \"%s\", 0)" % kind
+ cursor.execute(sql, param)
+ cursor.close()
+ return True
+ sql = "select * from auth_cnt where id = %%s and kind = \"%s\" and cnt <= %s" % (kind, limits)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ cursor.close()
+ if result is None:
+ return False
+ else:
+ return True
+
+ def incAuthCnt(self, uid, kind):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "update auth_cnt set cnt = cnt + 1 where id = %%s and kind = \"%s\"" % kind
+ param = (uid,)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ def addEmailCode(self, uid, code, period):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from email_code where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ sql = "insert into email_code(id, code, expire_in) values(%%s, %%s, unix_timestamp() + %s)" % period
+ param = (uid, code)
+ else:
+ sql = "update email_code set code = %%s, expire_in = unix_timestamp() + %s where id = %%s" % period
+ param = (code, uid)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ def checkEmailCode(self, uid, code):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from email_code where id = %s and code = %s and expire_in > unix_timestamp()"
+ param = (uid, code)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ return False
+ else:
+ return True
+
+ def deleteEmailCode(self, uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "delete from email_code where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ def setDailyTask(self):
+ while True:
+ time.sleep(24 * 3600)
+ self.clearAuthTempData()
+
+ def clearAuthTempData(self):
+ # clear auth_cnt table
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "delete from auth_cnt"
+ cursor.execute(sql)
+ self.db.commit()
+ # clear out date email code records
+ sql = "delete from email_code where expire_in < unix_timestamp()"
+ cursor.execute(sql)
+ self.db.commit()
+ cursor.close()
+
+ def addPhoneCode(self, uid, code, period):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from phone_code where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ sql = "insert into phone_code(id, code, expire_in) values(%%s, %%s, unix_timestamp() + %s)" % period
+ param = (uid, code)
+ else:
+ sql = "update phone_code set code = %%s, expire_in = unix_timestamp() + %s where id = %%s" % period
+ param = (code, uid)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+ pass
+
+ def checkPhoneCode(self, uid, code):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from phone_code where id = %s and code = %s and expire_in > unix_timestamp()"
+ param = (uid, code)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ return False
+ else:
+ return True
+
+ def deletePhoneCode(self, uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "delete from phone_code where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ self.db.commit()
+ cursor.close()
+
+ def operateScoreById(self,uid,score_op):
+ cursor = self.db.cursor()
+ if score_op > 0:
+ sql = "update info set score = score+%s where id = %s"
+ else:
+ sql = "update info set score = score-%s where id = %s"
+ param = (abs(score_op),uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+
+ def addScoreInfoById(self,uid):
+ cursor = self.db.cursor()
+ sql = "insert into score_info(id,login_time) values(%s,%s)"
+ param = (uid,"2000-01-01 00:00:00")
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+
+ def operateScoreInfoById(self,uid,cond,score_op):
+ cursor = self.db.cursor()
+ if score_op > 0:
+ sql = "update score_info set score"+str(cond)+" = score"+str(cond)+"+%s where id = %s"
+ else:
+ sql = "update score_info set score"+str(cond)+" = score"+str(cond)+"-%s where id = %s"
+ param = (abs(score_op),uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+
+ def getScoreInfoById(self,uid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select * from score_info where id = %s"
+ param = (uid,)
+ cursor.execute(sql, param)
+ result = cursor.fetchone()
+ if result is None:
+ return None
+ else:
+ return result
+
+ def setScoreTimeById(self,uid,curTime):
+ cursor = self.db.cursor()
+ sql = "update score_info set login_time = %s where id = %s"
+ param = (curTime,uid)
+ cursor.execute(sql,param)
+ self.db.commit()
+ cursor.close()
+
+ def getGreatestHelperId(self,eid):
+ cursor = self.db.cursor(cursorclass=MySQLdb.cursors.DictCursor)
+ sql = "select max(credit) from helper where eid = %s"
+ param = (eid,)
+ cursor.execute(sql, param)
+ cre = cursor.fetchone()
+ cre = cre['max(credit)']
+ sql = "select usrid from helper where eid = %s and credit = %s"
+ param = (eid,cre)
+ cursor.execute(sql, param)
+ result = cursor.fetchall()
+ return result
- '''.'''
def __del__(self):
self.db.close()
diff --git a/code/handler/AddaidHandler.py b/code/handler/AddaidHandler.py
deleted file mode 100644
index 4237333..0000000
--- a/code/handler/AddaidHandler.py
+++ /dev/null
@@ -1,17 +0,0 @@
-'''Yeqin Zheng, 09/07/2014'''
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os, json, sys
-sys.path.append("..")
-import dbapi
-
-''' Add a helper to an event. Succeed with "1" returned, else with "0". '''
-
-class AddaidHandler(tornado.web.RequestHandler):
- def post(self):
- u_name = self.get_argument('u_name')
- e_id = self.get_argument('e_id')
-
- result = self.application.dbapi.addaidhelper(u_name, e_id)
- self.write("{'state': " + result + "}")
\ No newline at end of file
diff --git a/code/handler/AddrelativesHandler.py b/code/handler/AddrelativesHandler.py
deleted file mode 100644
index 644d877..0000000
--- a/code/handler/AddrelativesHandler.py
+++ /dev/null
@@ -1,24 +0,0 @@
-'''Yeqin Zheng, 09/07/2014'''
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os, json, sys
-sys.path.append("..")
-import dbapi
-
-''' Add a relation between two users. Succeed with "1" returned, else with "0". '''
-
-class AddrelativesHandler(tornado.web.RequestHandler):
- def post(self):
- u_name = self.get_argument('u_name')
- r_name = self.get_argument('r_name')
-
- row = self.application.dbapi.getRelationByUsername(u_name, r_name)
- if row == 0:
- self.application.dbapi.addRelationByUsername(u_name, r_name)
- self.application.dbapi.addtempRelationByUsername(u_name, r_name)
- add_message = {'state': 1}
- else:
- add_message = {'state': 0}
-
- self.write(add_message)
diff --git a/code/handler/AuthenHandler.py b/code/handler/AuthenHandler.py
deleted file mode 100644
index 87385eb..0000000
--- a/code/handler/AuthenHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class AuthenHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("AuthenHandler")
diff --git a/code/handler/Authorize.py b/code/handler/Authorize.py
new file mode 100644
index 0000000..fdc2c18
--- /dev/null
+++ b/code/handler/Authorize.py
@@ -0,0 +1,346 @@
+# encoding: utf-8
+__author__ = 'Administrator'
+
+import tornado.web
+import json
+import random
+import smtplib
+from email.mime.text import MIMEText
+from CHRequestHandler import CHRequestHandler, LackParamsException, NoUserException
+#
+# errorcode:
+# 1: 缺少参数
+# 2: 用户名错误,用户不存在
+#
+# 查询用户的认证状态
+#
+class AuthStateHandler(tornado.web.RequestHandler):
+ def post(self):
+ print("mark 2")
+ content = self.request.body
+ j = json.loads(content)
+ if j.has_key("username"):
+ username = j["username"]
+ else:
+ error = {
+ "error": "lack params",
+ "request": "querauthstate",
+ "error_code": 1
+ }
+ self.write(json.dumps(error))
+ print("no username supplied")
+ return
+ user_record = self.application.dbapi.getUserByUserName(username)
+ if user_record is None:
+ error = {
+ "error": "no such user",
+ "request": "queryauthstate",
+ "error_code": 2
+ }
+ self.write(json.dumps(error))
+ print("no such user")
+ return
+ uid = user_record["id"]
+ auth_record = self.application.dbapi.getAuth(uid)
+ if auth_record is None:
+ self.application.dbapi.insertAuth(uid)
+ auth_record = self.application.dbapi.getAuth(uid)
+ result = {
+ "email": auth_record["email"],
+ "email_state": auth_record["email_state"],
+ "phone": auth_record["phone"],
+ "phone_state": auth_record["phone_state"]
+ }
+ print("mark 1")
+ resultstr = json.dumps(result)
+ print(resultstr)
+ self.write(resultstr)
+
+
+
+#
+# params:
+# username
+# email
+# error_code:
+# prefix: 10000
+class RequestEmailAuthHandler(tornado.web.RequestHandler):
+ codechars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW0123456789"
+
+ host = "114.215.133.61:8080"
+ mail_host = "smtp.163.com"
+ mail_user = "CommunityHelp"
+ mail_pass = "community"
+ mail_postfix = "163.com"
+ me = mail_user + "<" + mail_user + "@" + mail_postfix + ">"
+ msg_content_template = u"""
+
+
+
+
+
+
+ 社区居民求助系统邮箱验证
+ 您好!
+ 您已经成功发出了邮箱验证请求。
+ 点击以下链接即可完成邮箱验证。如果无法点击,请手动复制网址到浏览器打开。
+ http://%s/api/authemail?username=%s&code=%s
+ 请注意,本次验证的有效期为2天。在发送邮件之后的2天内任何时间都可以点击验证。
+ 如果超过三天还没有点击该链接,则验证将过期。您需要重新请求邮箱验证。
+ 每个用户每天可以请求10次邮箱验证。如果超过10次,请第二天再试。
+
+ """
+ msg_subject = "社区居民求助系统邮箱验证"
+
+ def post(self):
+ # get param
+ content = self.request.body
+ j = json.loads(content)
+ if j.has_key("username"):
+ username = j["username"]
+ else:
+ error = {
+ "error": "lack params",
+ "request": "requestemailauth",
+ "error_code": 1
+ }
+ self.write(json.dumps(error))
+ print("lack username")
+ return
+ # get uid
+ user_record = self.application.dbapi.getUserByUserName(username)
+ if user_record is None:
+ error = {
+ "error": "no such user",
+ "request": "requestemailauth",
+ "error_code": 2
+ }
+ self.write(json.dumps(error))
+ print("no such user")
+ return
+ uid = user_record["id"]
+ # get auth record
+ auth_record = self.application.dbapi.getAuth(uid)
+ if auth_record is None:
+ print "mark 2.1"
+ self.application.dbapi.insertAuth(uid)
+ print "mark 2.2"
+ auth_record = self.application.dbapi.getAuth(uid)
+ # if authed, return error
+ if auth_record["email_state"] == "authed":
+ error = {
+ "error": "authed",
+ "request": "requestemailauth",
+ "error_code": 10001
+ }
+ self.write(json.dumps(error))
+ return
+ # find email
+ if j.has_key("email"):
+ email = j["email"]
+ self.application.dbapi.updateAuthData(uid, "email", email)
+ elif auth_record["email"] != "":
+ email = auth_record["email"]
+ else:
+ error = {
+ "error": "lack params",
+ "request": "requestemailauth",
+ "error_code": 1
+ }
+ self.write(json.dumps(error))
+ return
+ # check request times
+ if not self.application.dbapi.checkAuthCnt(uid, "email", 10):
+ error = {
+ "error": "reach request limits",
+ "request": "requestemailauth",
+ "error_code": 10002
+ }
+ self.write(json.dumps(error))
+ return
+ # update auth count
+ self.application.dbapi.incAuthCnt(uid, "email")
+ # send email
+ code = self.getCode(50)
+ if not self.sendAuthEmail(email, username, code):
+ error = {
+ "error": "send email failed",
+ "request": "requestemailauth",
+ "error_code": 10003
+ }
+ self.write(json.dumps(error))
+ return
+ # insert email code record
+ period = 2 * 24 * 3600
+ self.application.dbapi.addEmailCode(uid, code, period)
+ # update auth state
+ self.application.dbapi.updateAuthState(uid, "email", "authing")
+ result = {
+ "result": "OK"
+ }
+ self.write(json.dumps(result))
+
+ def getCode(self, num):
+ code = ""
+ for i in range(0, num):
+ code += random.choice(RequestEmailAuthHandler.codechars)
+ return code
+
+ def fillMsg(self, username, code):
+ msg_content = RequestEmailAuthHandler.msg_content_template % (RequestEmailAuthHandler.host, username, code, RequestEmailAuthHandler.host, username, code)
+ return msg_content
+
+ def sendAuthEmail(self, email, username, code):
+ msg_content = self.fillMsg(username, code)
+ msg = MIMEText(msg_content, _subtype = "html", _charset="utf-8")
+ msg["Subject"] = RequestEmailAuthHandler.msg_subject
+ msg["From"] = RequestEmailAuthHandler.me
+ msg["To"] = email
+ try:
+ s = smtplib.SMTP()
+ s.connect(RequestEmailAuthHandler.mail_host)
+ s.login(RequestEmailAuthHandler.mail_user, RequestEmailAuthHandler.mail_pass)
+ s.sendmail(RequestEmailAuthHandler.me, email, msg.as_string())
+ s.close()
+ return True
+ except Exception as e:
+ return False
+ print str(e)
+# params:
+# username
+# code
+# error_code:
+# prefix: 20000
+class AuthEmailHandler(tornado.web.RequestHandler):
+ def get(self):
+ try:
+ username = self.get_argument("username")
+ code = self.get_argument("code")
+ except:
+ error = {
+ "error": "lack params",
+ "request": "requestemailauth",
+ "error_code": 1
+ }
+ self.write(json.dumps(error))
+ return
+ # get uid
+ user_record = self.application.dbapi.getUserByUserName(username)
+ if user_record is None:
+ error = {
+ "error": "no such user",
+ "request": "authemail",
+ "error_code": 1
+ }
+ self.write(json.dumps(error))
+ print("no such user")
+ return
+ uid = user_record["id"]
+ if self.application.dbapi.checkEmailCode(uid, code):
+ self.application.dbapi.updateAuthState(uid, "email", "authed")
+ self.application.dbapi.deleteEmailCode(uid)
+ result = {
+ "result":"OK"
+ }
+ self.write(json.dumps(result))
+ return
+ else:
+ error = {
+ "error": "email auth code error",
+ "request": "authemail",
+ "error_code": 20001
+ }
+ self.write(json.dumps(error))
+ return
+
+# 30001 已认证
+# 30002 超过验证次数
+# 30003 发送短信错误
+class RequestPhoneAuthHandler(CHRequestHandler):
+ codechars = "0123456789"
+
+ def post(self):
+ try:
+ j = self.getParams(["username", "phone"])
+ uid = self.getUserId(j["username"])
+ phone = j["phone"]
+ except LackParamsException:
+ self.writeError(1, "requestphoneauth")
+ return
+ except NoUserException:
+ self.writeError(2, "requestphoneauth")
+ return
+ auth_record = self.application.dbapi.getAuth(uid)
+ if auth_record is None:
+ self.application.dbapi.insertAuth(uid)
+ auth_record = self.application.dbapi.getAuth(uid)
+ if auth_record["phone_state"] == "authed":
+ self.writeError(30001, "requestphoneauth")
+ return
+ if not self.application.dbapi.checkAuthCnt(uid, "phone", 10):
+ self.writeError(30002, "requestphoneauth")
+ return
+ self.application.dbapi.incAuthCnt(uid, "phone")
+ code = self.getCode(6)
+ minutes = 10
+ if not self.sendSMS(phone, code, minutes):
+ self.writeError(30003, "requestphoneauth")
+ period = minutes * 60
+ self.application.dbapi.addPhoneCode(uid, code, period)
+ self.application.dbapi.updateAuthData(uid, "phone", phone)
+ self.application.dbapi.updateAuthState(uid, "phone", "authing")
+ self.writeOK()
+
+
+ def getCode(self, num):
+ code = ""
+ for i in range(0, num):
+ code += random.choice(RequestPhoneAuthHandler.codechars)
+ return code
+
+ def sendSMS(self, phone, code, minutes):
+ datas = [code, minutes]
+ return sendTemplateSMS(phone, datas, 1)
+
+from CCPRestSDK import *
+
+accountSid = "aaf98f89476703de01477c05267506ef"
+accountToken = "6b34f62bcc964167a6997286bb9a3f2f"
+appId = "aaf98f89476703de01477fc1dda307b1"
+serverIP = "sandboxapp.cloopen.com"
+serverPort = "8883"
+softVersion = "2013-12-26"
+
+def sendTemplateSMS(to, datas, temId):
+ rest = REST(serverIP, serverPort, softVersion)
+ rest.setAccount(accountSid, accountToken)
+ rest.setAppId(appId)
+ result = rest.sendTemplateSMS(to, datas, temId)
+ if result["statusCode"] == "000000":
+ return True
+ else:
+ return False
+
+
+# 40001 验证失败
+class AuthPhoneHandler(CHRequestHandler):
+
+ def post(self):
+ try:
+ j = self.getParams(["username", "code"])
+ uid = self.getUserId(j["username"])
+ code = j["code"]
+ except LackParamsException:
+ self.writeError(1, "authphone")
+ return
+ except NoUserException:
+ self.writeError(2, "authphone")
+ return
+ if self.application.dbapi.checkPhoneCode(uid, code):
+ self.application.dbapi.updateAuthState(uid, "phone", "authed")
+ self.application.dbapi.deletePhoneCode(uid)
+ self.writeOK()
+ return
+ else:
+ self.writeError(40001, "authphone")
+ return
diff --git a/code/handler/CCPRestSDK.py b/code/handler/CCPRestSDK.py
new file mode 100644
index 0000000..5944842
--- /dev/null
+++ b/code/handler/CCPRestSDK.py
@@ -0,0 +1,656 @@
+ #-*- coding: UTF-8 -*-
+ # Copyright (c) 2014 The CCP project authors. All Rights Reserved.
+ #
+ # Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license
+ # that can be found in the LICENSE file in the root of the web site.
+ #
+ # http://www.yuntongxun.com
+ #
+ # An additional intellectual property rights grant can be found
+ # in the file PATENTS. All contributing project authors may
+ # be found in the AUTHORS file in the root of the source tree.
+
+import md5
+import base64
+import datetime
+import urllib2
+import json
+from xmltojson import xmltojson
+from xml.dom import minidom
+
+class REST:
+
+ AccountSid=''
+ AccountToken=''
+ AppId=''
+ SubAccountSid=''
+ SubAccountToken=''
+ VoIPAccount=''
+ VoIPPassword=''
+ ServerIP=''
+ ServerPort=''
+ SoftVersion=''
+ Iflog=True #是否打印日志
+ Batch='' #时间戳
+ BodyType = 'json'#包体格式,可填值:json 、xml
+
+ # 初始化
+ # @param serverIP 必选参数 服务器地址
+ # @param serverPort 必选参数 服务器端口
+ # @param softVersion 必选参数 REST版本号
+ def __init__(self,ServerIP,ServerPort,SoftVersion):
+
+ self.ServerIP = ServerIP;
+ self.ServerPort = ServerPort;
+ self.SoftVersion = SoftVersion;
+
+
+ # 设置主帐号
+ # @param AccountSid 必选参数 主帐号
+ # @param AccountToken 必选参数 主帐号Token
+
+ def setAccount(self,AccountSid,AccountToken):
+ self.AccountSid = AccountSid;
+ self.AccountToken = AccountToken;
+
+
+ # 设置子帐号
+ #
+ # @param SubAccountSid 必选参数 子帐号
+ # @param SubAccountToken 必选参数 子帐号Token
+ # @param VoIPAccount 必选参数 VoIP帐号
+ # @param VoIPPassword 必选参数 VoIP密码
+
+ def setSubAccount(self,SubAccountSid,SubAccountToken,VoIPAccount,VoIPPassword):
+ self.SubAccountSid = SubAccountSid;
+ self.SubAccountToken = SubAccountToken;
+ self.VoIPAccount = VoIPAccount;
+ self.VoIPPassword = VoIPPassword;
+
+ # 设置应用ID
+ #
+ # @param AppId 必选参数 应用ID
+
+ def setAppId(self,AppId):
+ self.AppId = AppId;
+
+ def log(self,url,body,data):
+ print('这是请求的URL:')
+ print (url);
+ print('这是请求包体:')
+ print (body);
+ print('这是响应包体:')
+ print (data);
+ print('********************************')
+
+
+ # 创建子账号
+ # @param friendlyName 必选参数 子帐号名称
+ def CreateSubAccount(self, friendlyName):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/SubAccounts?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ req.add_header("Authorization", auth)
+ #xml格式
+ body ='''%s\
+ %s\
+ \
+ '''%(self.AppId, friendlyName)
+
+ if self.BodyType == 'json':
+ #json格式
+ body = '''{"friendlyName": "%s", "appId": "%s"}'''%(friendlyName,self.AppId)
+ data=''
+ req.add_data(body)
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 获取子帐号
+ # @param startNo 可选参数 开始的序号,默认从0开始
+ # @param offset 可选参数 一次查询的最大条数,最小是1条,最大是100条
+ def getSubAccounts(self, startNo,offset):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/GetSubAccounts?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ req.add_header("Authorization", auth)
+ #xml格式
+ body ='''%s\
+ %s%s\
+ \
+ '''%(self.AppId, startNo, offset)
+
+ if self.BodyType == 'json':
+ #json格式
+ body = '''{"appId": "%s", "startNo": "%s", "offset": "%s"}'''%(self.AppId,startNo,offset)
+ data=''
+ req.add_data(body)
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 子帐号信息查询
+ # @param friendlyName 必选参数 子帐号名称
+
+ def querySubAccount(self, friendlyName):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/QuerySubAccountByName?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''%s\
+ %s\
+ \
+ '''%(self.AppId, friendlyName)
+ if self.BodyType == 'json':
+
+ body = '''{"friendlyName": "%s", "appId": "%s"}'''%(friendlyName,self.AppId)
+ data=''
+ req.add_data(body)
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 发送模板短信
+ # @param to 必选参数 短信接收彿手机号码集合,用英文逗号分开
+ # @param datas 可选参数 内容数据
+ # @param tempId 必选参数 模板Id
+ def sendTemplateSMS(self, to,datas,tempId):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/SMS/TemplateSMS?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ req.add_header("Authorization", auth)
+ #创建包体
+ b=''
+ for a in datas:
+ b+='%s'%(a)
+
+ body =''+b+'%s%s%s\
+ \
+ '%(to, tempId,self.AppId)
+ if self.BodyType == 'json':
+ # if this model is Json ..then do next code
+ b='['
+ for a in datas:
+ b+='"%s",'%(a)
+ b+=']'
+ body = '''{"to": "%s", "datas": %s, "templateId": "%s", "appId": "%s"}'''%(to,b,tempId,self.AppId)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 双向回呼
+ # @param fromPhone 必选参数 主叫电话号码
+ # @param to 必选参数 被叫电话号码
+ # @param customerSerNum 可选参数 被叫侧显示的客服号码
+ # @param fromSerNum 可选参数 主叫侧显示的号码
+ # @param promptTone 可选参数 第三方自定义回拨提示音
+
+ def callBack(self,fromPhone,to,customerSerNum,fromSerNum,promptTone):
+
+ self.subAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.SubAccountSid + self.SubAccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/SubAccounts/" + self.SubAccountSid + "/Calls/Callback?sig=" + sig
+ #生成auth
+ src = self.SubAccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''\
+ %s%s%s%s%s\
+ \
+ '''%(fromPhone, to,customerSerNum,fromSerNum,promptTone)
+ if self.BodyType == 'json':
+ body = '''{"from": "%s", "to": "%s","customerSerNum": "%s","fromSerNum": "%s","promptTone": "%s"}'''%(fromPhone, to,customerSerNum,fromSerNum,promptTone)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+ # 营销外呼
+ # @param to 必选参数 被叫号码
+ # @param mediaName 可选参数 语音文件名称,格式 wav。与mediaTxt不能同时为空。当不为空时mediaTxt属性失效。
+ # @param mediaTxt 可选参数 文本内容
+ # @param displayNum 可选参数 显示的主叫号码
+ # @param playTimes 可选参数 循环播放次数,1-3次,默认播放1次。
+ # @param respUrl 可选参数 营销外呼状态通知回调地址,云通讯平台将向该Url地址发送呼叫结果通知。
+
+ def landingCall(self,to,mediaName,mediaTxt,displayNum,playTimes,respUrl):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/Calls/LandingCalls?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''\
+ %s%s%s%s%s\
+ %s%s\
+ '''%(to, mediaName,mediaTxt,self.AppId,displayNum,playTimes,respUrl)
+ if self.BodyType == 'json':
+ body = '''{"to": "%s", "mediaName": "%s","mediaTxt": "%s","appId": "%s","displayNum": "%s","playTimes": "%s","respUrl": "%s"}'''%(to, mediaName,mediaTxt,self.AppId,displayNum,playTimes,respUrl)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 语音验证码
+ # @param verifyCode 必选参数 验证码内容,为数字和英文字母,不区分大小写,长度4-8位
+ # @param playTimes 可选参数 播放次数,1-3次
+ # @param to 必选参数 接收号码
+ # @param displayNum 可选参数 显示的主叫号码
+ # @param respUrl 可选参数 语音验证码状态通知回调地址,云通讯平台将向该Url地址发送呼叫结果通知
+
+ def voiceVerify(self,verifyCode,playTimes,to,displayNum,respUrl):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/Calls/VoiceVerify?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''\
+ %s%s%s%s%s\
+ %s\
+ '''%(self.AppId,verifyCode,playTimes,to,respUrl,displayNum)
+ if self.BodyType == 'json':
+ # if this model is Json ..then do next code
+ body = '''{"appId": "%s", "verifyCode": "%s","playTimes": "%s","to": "%s","respUrl": "%s","displayNum": "%s"}'''%(self.AppId,verifyCode,playTimes,to,respUrl,displayNum)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # IVR外呼
+ # @param number 必选参数 待呼叫号码,为Dial节点的属性
+ # @param userdata 可选参数 用户数据,在通知中返回,只允许填写数字字符,为Dial节点的属性
+ # @param record 可选参数 是否录音,可填项为true和false,默认值为false不录音,为Dial节点的属性
+
+ def ivrDial(self,number,userdata,record):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/ivr/dial?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ req.add_header("Accept", "application/xml")
+ req.add_header("Content-Type", "application/xml;charset=utf-8")
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''
+
+ %s
+
+
+ '''%(self.AppId,number,userdata,record)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+
+ # 话单下载
+ # @param date 必选参数 day 代表前一天的数据(从00:00 – 23:59);week代表前一周的数据(周一 到周日);month表示上一个月的数据(上个月表示当前月减1,如果今天是4月10号,则查询结果是3月份的数据)
+ # @param keywords 可选参数 客户的查询条件,由客户自行定义并提供给云通讯平台。默认不填忽略此参数
+ def billRecords(self,date,keywords):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/BillRecords?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ req.add_header("Authorization", auth)
+
+ #创建包体
+ body ='''\
+ %s%s%s\
+ \
+ '''%(self.AppId,date,keywords)
+ if self.BodyType == 'json':
+ # if this model is Json ..then do next code
+ body = '''{"appId": "%s", "date": "%s","keywords": "%s"}'''%(self.AppId,date,keywords)
+ req.add_data(body)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ # 主帐号信息查询
+
+ def queryAccountInfo(self):
+
+ self.accAuth()
+ nowdate = datetime.datetime.now()
+ self.Batch = nowdate.strftime("%Y%m%d%H%M%S")
+ #生成sig
+ signature = self.AccountSid + self.AccountToken + self.Batch;
+ sig = md5.new(signature).hexdigest().upper()
+ #拼接URL
+ url = "https://"+self.ServerIP + ":" + self.ServerPort + "/" + self.SoftVersion + "/Accounts/" + self.AccountSid + "/AccountInfo?sig=" + sig
+ #生成auth
+ src = self.AccountSid + ":" + self.Batch;
+ auth = base64.encodestring(src).strip()
+ req = urllib2.Request(url)
+ self.setHttpHeader(req)
+ body=''
+ req.add_header("Authorization", auth)
+ data=''
+ try:
+ res = urllib2.urlopen(req);
+ data = res.read()
+ res.close()
+
+ if self.BodyType=='json':
+ #json格式
+ locations = json.loads(data)
+ else:
+ #xml格式
+ xtj=xmltojson()
+ locations=xtj.main(data)
+ if self.Iflog:
+ self.log(url,body,data)
+ return locations
+ except Exception, error:
+ if self.Iflog:
+ self.log(url,body,data)
+ return {'172001':'网络错误'}
+
+ #子帐号鉴权
+ def subAuth(self):
+ if(self.ServerIP==""):
+ print('172004');
+ print('IP为空');
+
+ if(self.ServerPort<=0):
+ print('172005');
+ print('端口错误(小于等于0)');
+
+ if(self.SoftVersion==""):
+ print('172013');
+ print('版本号为空');
+
+ if(self.SubAccountSid==""):
+ print('172008');
+ print('子帐号为空');
+
+ if(self.SubAccountToken==""):
+ print('172009');
+ print('子帐号令牌为空');
+
+ if(self.AppId==""):
+ print('172012');
+ print('应用ID为空');
+
+ #主帐号鉴权
+ def accAuth(self):
+ if(self.ServerIP==""):
+ print('172004');
+ print('IP为空');
+
+ if(self.ServerPort<=0):
+ print('172005');
+ print('端口错误(小于等于0)');
+
+ if(self.SoftVersion==""):
+ print('172013');
+ print('版本号为空');
+
+ if(self.AccountSid==""):
+ print('172006');
+ print('主帐号为空');
+
+ if(self.AccountToken==""):
+ print('172007');
+ print('主帐号令牌为空');
+
+ if(self.AppId==""):
+ print('172012');
+ print('应用ID为空');
+
+
+
+ #设置包头
+ def setHttpHeader(self,req):
+ if self.BodyType == 'json':
+ req.add_header("Accept", "application/json")
+ req.add_header("Content-Type", "application/json;charset=utf-8")
+
+ else:
+ req.add_header("Accept", "application/xml")
+ req.add_header("Content-Type", "application/xml;charset=utf-8")
+
\ No newline at end of file
diff --git a/code/handler/CHRequestHandler.py b/code/handler/CHRequestHandler.py
new file mode 100644
index 0000000..89c3125
--- /dev/null
+++ b/code/handler/CHRequestHandler.py
@@ -0,0 +1,41 @@
+__author__ = 'Administrator'
+
+import tornado.web
+import json
+
+class NoUserException(Exception):
+ def __init__(self):
+ pass
+
+class LackParamsException(Exception):
+ def __init__(self):
+ pass
+
+class CHRequestHandler(tornado.web.RequestHandler):
+ def getUserId(self, username):
+ record = self.application.dbapi.getUserByUserName(username)
+ if record is None:
+ raise NoUserException()
+ return record["id"]
+
+ def getParams(self, essentials = []):
+ j = json.loads(self.request.body)
+ for k in essentials:
+ if not j.has_key(k):
+ raise LackParamsException()
+ return j
+
+ def writeError(self, error_code, apiname):
+ error = {
+ "result": "error",
+ "request": apiname,
+ "error_code": error_code
+ }
+ self.write(json.dumps(error))
+
+ def writeOK(self):
+ result = {
+ "result": "ok"
+ }
+ self.write(result)
+
diff --git a/code/handler/CancelHandler.py b/code/handler/CancelHandler.py
deleted file mode 100644
index 752746e..0000000
--- a/code/handler/CancelHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class CancelHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("CancelHandler")
diff --git a/code/handler/CheckrelativesHandler.py b/code/handler/CheckrelativesHandler.py
deleted file mode 100644
index 9745dd5..0000000
--- a/code/handler/CheckrelativesHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class CheckrelativesHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("CheckrelativesHandler")
diff --git a/code/handler/DeleterelativesHandler.py b/code/handler/DeleterelativesHandler.py
deleted file mode 100644
index e5df91c..0000000
--- a/code/handler/DeleterelativesHandler.py
+++ /dev/null
@@ -1,25 +0,0 @@
-'''Yeqin Zheng, 09/07/2014'''
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os, json, sys
-sys.path.append("..")
-import dbapi
-
-''' Delete a relation between two users. Succeed with "1" returned, else with "0". '''
-
-class DeleterelativesHandler(tornado.web.RequestHandler):
- def post(self):
- #self.write(u_id + r_id)
- u_name = self.get_argument('u_name')
- r_name = self.get_argument('r_name')
-
- row = self.application.dbapi.getRelationByUsername(u_name, r_name)
- #self.write(row2)
- if row == 0 :
- delete_message = {'state': 0}
- else :
- self.application.dbapi.deleteRelationByUsername(u_name, r_name)
- delete_message = {'state': 1}
-
- self.write(delete_message)
diff --git a/code/handler/EventHandler.py b/code/handler/EventHandler.py
new file mode 100644
index 0000000..9b6886c
--- /dev/null
+++ b/code/handler/EventHandler.py
@@ -0,0 +1,296 @@
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+from tornado.escape import *
+from sets import Set
+import json
+
+class HelpmessageHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("HelpmessageHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content='{"username":"test1","message":{"kind":1,"content":"TestContent", "video":"TestAssist","videosign":1,"audeo":"dsds","audiosign":1,"latitude":23.000000,"longitude":23.000000}}'
+ jobj=json.loads(content)
+ result = self.application.dbapi.addEventByUserName(jobj["username"],jobj["message"])
+ self.write(json_encode(result))
+
+ if(jobj['message']['videosign'] =="1"):
+ print "test1"
+ self.application.util.setVideobyEid(result['eventid'],jobj['video'])
+
+ if(jobj['message']['audiosign'] =="1"):
+ print "test2"
+ self.application.util.setAudiobyEid(result['eventid'],jobj['audio'])
+
+ """if(result["state"] == 1):
+ eventinfo = self.application.dbapi.getEventandUserByEventId(result['eventid'])
+ eventinfo['audio'] = jobj['message']['videosign']
+ eventinfo['video'] = jobj['message']['audiosign']
+ print '{"type":"help","data":'+json_encode(eventinfo)+'}'
+ info = self.application.dbapi.getUserInfobyName(jobj["username"])
+ cidlist = self.application.dbapi.getUserCidAround(info["longitude"],info["latitude"],5)
+ relativelist = self.application.dbapi.getRelativesCidbyUid(info['id'])
+ cidlist.extend(relativelist)
+ cidlist = list(Set(cidlist))
+ cidlist.remove(info['cid'])
+ print cidlist
+ self.application.push.pushToList(cidlist,'{"type":"help","data":'+json_encode(eventinfo)+'}')"""
+ if(result["state"] == 1):
+ eventinfo = self.application.dbapi.getEventandUserByEventId(result['eventid'])
+ eventinfo['audio'] = jobj['message']['videosign']
+ eventinfo['video'] = jobj['message']['audiosign']
+ pushlist = []
+ askuser = self.application.dbapi.getUserInfobyName(jobj["username"])
+ relativelist = self.application.dbapi.getRelativesCidbyUid(askuser['id'])
+ print relativelist
+ pushlist.extend(relativelist)
+ friendlist = self.application.dbapi.getRelativesIdbyUid(askuser['id'])
+ hashelpaskuserlist = self.application.dbapi.getHelpersIdbyUid(askuser['id'])
+ distance = 3
+ special = []
+ if(jobj['message']['kind'] ==1):#anquan
+ print 1
+ special = self.application.dbapi.getAroundbyvocationOrKind(askuser["longitude"],askuser["latitude"],1,4,20,5)
+ print special
+ pushlist.extend(special)
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,1)
+ while len(aroundhelpers) <= 50 and distance <= 7:
+ distance +=2
+ aroundhelpers= self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,1)
+
+
+ elif(jobj['message']['kind'] ==2):
+ print 2
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,2)
+ while len(aroundhelpers) <= 10 and distance <= 7:
+ distance +=2
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,2)
+
+ else:#jiankang
+ print 3
+ special = self.application.dbapi.getAroundbyvocationOrKind(askuser["longitude"],askuser["latitude"],1,5,10,5)
+ print special
+ pushlist.extend(special)
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,3)
+ while len(aroundhelpers) <= 20 and distance <= 5:
+ distance +=2
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],distance,3)
+
+ predictlist = self.application.util.getPushlistByCredit(askuser,aroundhelpers,friendlist,hashelpaskuserlist,0.5,self.application.dbapi)
+ print predictlist
+ pushlist.extend(predictlist)
+ pushlist = list(Set(pushlist))
+ if(askuser['cid'] in pushlist):
+ pushlist.remove(askuser['cid'])
+ print pushlist
+ self.application.push.pushToList(pushlist,'{"type":"help","data":'+json_encode(eventinfo)+'}')
+ return
+
+class EventHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("eventHandler
")
+
+ def post(self):
+ content=self.request.body
+ #content='{"username":"test4","eventid":1}'
+ jobj=json.loads(content)
+ uid = self.application.dbapi.getUserByUserName(jobj['username'])["id"]
+ helpevent=self.application.dbapi.getEventandUserByEventId(jobj['eventid'])
+ print helpevent
+ result={}
+ if(helpevent):
+ helpevent['follows'] = self.application.dbapi.getFollowsByEventId(jobj['eventid'])['count']
+ helpevent['helpers'] = len(self.application.dbapi.getHelpersCidbyEid(jobj['eventid']))
+ result['event'] = helpevent
+ ishelper = self.application.dbapi.checkifUseraddHelper(uid,jobj['eventid'])
+ if(ishelper is None):
+ if(helpevent['username'] == jobj['username']):
+ result['ishelper'] = 1
+ else:
+ result['ishelper'] = 0
+ else:
+ result['ishelper'] = 1
+ rNamelist = self.application.dbapi.getAllRelativeNamebyUid(helpevent['userid'])
+ print rNamelist
+ if(uid in rNamelist):
+ result['canend'] = 1
+ else:
+ result['canend'] = 0
+ if(self.application.dbapi.getFollow(uid,jobj['eventid']) is None):
+ if(helpevent['username'] == jobj['username']):
+ result['isfollow'] = 1
+ else:
+ result['isfollow'] = 0
+ else:
+ result['isfollow'] = 1
+ print result
+ result['support']=self.application.dbapi.getSupportsByEventId(jobj['eventid'])
+ for support in result['support']:
+ user=self.application.dbapi.getUserByUserId(support['usrid'])
+ if(user):
+ support['username']=user['name'];
+ avatar=self.application.util.getAvatarbyUid(support['usrid'])
+ support['avatar']=avatar
+ self.write(json_encode(result))
+
+'''Yeqin Zheng, 09/07/2014'''
+''' Add a helper to an event. Succeed with "1" returned, else with "0". '''
+class AddaidHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("AddaidHandler
")
+ def post(self):
+ content = self.request.body
+ #content = '{"username":"test1","eventid":"4"}'
+ j = json.loads(content)
+
+ result = self.application.dbapi.addaidhelper(j['username'], j['eventid'])
+ self.write("{'state': " + result + "}")
+ uid =self.application.dbapi.getUserByUserName(j['username'])['id']
+ self.application.score.joinSupport(uid,self.application.dbapi)
+
+
+class FinishHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("FinishHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"test1","eventid":1}'
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ event = self.application.dbapi.getEventandUserByEventId(j['eventid'])
+ if(event is None):
+ self.write("{'state':1}")
+ print "event not exist"
+ return
+ rNamelist = self.application.dbapi.getAllRelativeNamebyUid(event["userid"])
+ if(user["id"] not in rNamelist):
+ self.write("{'state':2}")
+ print "user not relative or itself,can not update sate"
+ return
+ currenttime = self.application.dbapi.changeEventState(j['eventid'])
+ helpers = self.application.dbapi.getHelperInfoByEid(j['eventid'])
+ data = []
+ for item in helpers:
+ info = {}
+ info['username'] = item['username']
+ info['uid'] = item['uid']
+ data.append(info)
+ self.application.dbapi.UpdateInfotimebyUid(item['uid'])
+ #data.append("{'username':" + str(item['username']) + ",'uid':"+ str(item['uid'])+"}")
+ writedata = {}
+ writedata['state'] = 3
+ writedata['helpers'] = data
+ #push
+ pushlist = self.application.dbapi.getFollowerCidByEid(j['eventid'])
+ helperlist = self.application.dbapi.getHelpersCidbyEid(j['eventid'])
+ pushlist.extend(helperlist)
+ relativelist = self.application.dbapi.getRelativesCidbyUid(event["userid"])
+ pushlist.extend(relativelist)
+ pushlist = list(Set(pushlist))
+ if(user['cid'] in pushlist):
+ pushlist.remove(user['cid'])
+ pushdata = {}
+ data = {}
+ pushdata['type'] = "endhelp"
+ data['eventid'] = j['eventid']
+ data['time'] = currenttime.strftime('%Y-%m-%d %H:%M:%S')
+ data['username'] = event['username']
+ pushdata['data'] = data
+ self.application.push.pushToList(pushlist,json_encode(pushdata))
+ self.write(json_encode(writedata))
+ print "finsh an event"
+ return
+
+
+class GivecreditHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("GivecreditHandler
")
+ def post(self):
+ content =self.request.body
+ #content='{"eventid":4,"helpername":"test2","credit":3}'
+ #content='{"eventid":1,"credits":[{"username":"test2","cridit":5},{"username":"test6","cridit":1}]}'
+ jobj=json.loads(content)
+ result=[]
+ event = self.application.dbapi.getEventByEventId(jobj['eventid'])
+ askuser = self.application.dbapi.getUserInfobyUid(event['usrid'])
+ for issue in jobj["credits"]:
+ temp = self.application.dbapi.setCreditByEventIdAndUserName(jobj["eventid"],issue["username"],issue["cridit"])
+ result.append({"helpername":issue["username"],"result":temp})
+ helper = self.application.dbapi.getUserInfobyName(issue['username'])
+ self.application.util.setCreditforHelper(event,askuser,helper,issue["cridit"],self.application.dbapi)
+ self.write(str(result))
+ self.application.score.giveCredit(event['usrid'],jobj['eventid'],self.application.dbapi)
+
+class QuitaidHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("QuitaidHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"oo11o","eventid":5}'
+ j = json.loads(content)
+ uid = self.application.dbapi.getUserByUserName(j['username'])['id']
+ if(self.application.dbapi.getEventByEventId(j['eventid'])['state'] == 1):
+ print "current had been end,you can not quit"
+ self.write("{'state':3}")
+ return
+
+ if(self.application.dbapi.checkifUseraddHelper(uid,j['eventid']) is None):
+ print "user " + j['username'] +" do not add the aid first"
+ self.write("{'state':2}")
+ return
+ self.application.dbapi.deleteHelperbyUidEid(uid,j['eventid'])
+ print "quit success"
+ self.write("{'state':1}")
+ application.score.quitSupport(uid,self.application.dbapi)
+ return
+
+class SendsupportHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("SendsupportHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content='{"username":"test1","eid":4,"message":{"content":"TestssCofffntent"}}'
+ jobj=json.loads(content)
+ user = self.application.dbapi.getUserByUserName(jobj['username'])
+ result=self.application.dbapi.addSupportByEventIdAndUserName(jobj["eid"],jobj["username"],jobj["message"])
+ if(result['errorCode'] == 200):
+ pushlist = self.application.dbapi.getFollowerCidByEid(jobj['eid'])
+ relativelist =self.application.dbapi.getRelativesCidbyUid(user['id'])
+ pushlist.extend(relativelist)
+ pushlist = list(Set(pushlist))
+ if(user['cid'] in pushlist):
+ pushlist.remove(user['cid'])
+ eventuser = self.application.dbapi.getUserByEid(jobj['eid'])
+ if(eventuser['uid'] !=user['id']):
+ pushlist.append(eventuser['cid'])
+ datatemp = self.application.dbapi.getSupportBySid(result['supportid'])
+ pushdata = {}
+ data = {}
+ pushdata['type'] = 'aid'
+ data['username'] = jobj['username']
+ data['content'] = datatemp['content']
+ data['time'] = datatemp['time'].strftime('%Y-%m-%d %H:%M:%S')
+ data['eventid'] = jobj['eid']
+ pushdata['data'] = data
+ self.application.push.pushToList(pushlist,json_encode(pushdata))
+ self.write(json_encode(result))
+ self.application.score.sendSupport(user['id'],self.application.dbapi)
+
+
+class SupportmessageHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("SupportmessageHandler
")
+
+ def post(self):
+ content =self.request.body
+ content = '{"eventid": 3,"video": "ssssssssssssssss","audio":"ddddd"}'
+ j = json.loads(content)
+ if('video' in j):
+ self.application.util.setVideobyEid(j['eid'],j['video'])
+ if('audio' in j):
+ self.application.util.setAudiobyEid(j['eid'],j['video'])
diff --git a/code/handler/FinishHandler.py b/code/handler/FinishHandler.py
deleted file mode 100644
index d142506..0000000
--- a/code/handler/FinishHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class FinishHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("FinishHandler")
diff --git a/code/handler/FollowHandler.py b/code/handler/FollowHandler.py
new file mode 100644
index 0000000..70c725e
--- /dev/null
+++ b/code/handler/FollowHandler.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+import json
+
+class startFollowHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("startFollowHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content='{"eid":2,"username":"test2"}'
+ j=json.loads(content)
+ user=self.application.dbapi.getUserByUserName(j['username'])["id"]
+ if(user):
+ if(self.application.dbapi.getFollow(user,j['eid'])):
+ data={'state':3,'desc':"have been followed"}#have been followed
+ result=json.dumps(data)
+ else:
+ self.application.dbapi.insertFollow(user,j['eid'])
+ data={'state':1,'desc':"start follow success"}#start follow success
+ result=json.dumps(data)
+ else:
+ data={'state':2,'desc':"user no exist"}#user no exist
+ result=json.dumps(data)
+ self.write(result)
+ return
+
+class cancelFollowHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("cancelFollowHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content='{"eid":2,"username":"test2"}'
+ j=json.loads(content)
+ user=self.application.dbapi.getUserByUserName(j['username'])["id"]
+ if(user):
+ if(self.application.dbapi.getFollow(user,j['eid'])):
+ self.application.dbapi.delectFollow(user,j['eid'])
+ data={'state':1,'desc':"delete follow success"}#delete follow success
+ result=json.dumps(data)
+ else:
+ data={'state':3,'desc':"have no follow"}#have no follow
+ result=json.dumps(data)
+ else:
+ data={'state':2,'desc':"user no exist"}#user no exist
+ result=json.dumps(data)
+ self.write(result)
+ return
diff --git a/code/handler/GetArroundEvent.py b/code/handler/GetArroundEvent.py
new file mode 100644
index 0000000..839739f
--- /dev/null
+++ b/code/handler/GetArroundEvent.py
@@ -0,0 +1,24 @@
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+from tornado.escape import *
+import json
+
+class GetArroundEvent(tornado.web.RequestHandler):
+ def get(self):
+ self.write("GetArroundEvent
")
+
+ def post(self):
+ content =self.request.body
+ j=json.loads(content)
+ user = self.application.dbapi.getUserInfobyName(j['username'])
+ if(user is None):
+ self.write("{'state':2}")
+ print "username not exist"
+ return
+ result = self.application.dbapi.getEventAround(user['longitude'],user['latitude'],5)
+ print result
+ for item in result:
+ item['avatar'] = self.application.util.getAvatar(item['name'],self.application.dbapi)
+ self.write("{'state':1,aids:"+json_encode(result)+"}")
+ return
diff --git a/code/handler/GivecreditHandler.py b/code/handler/GivecreditHandler.py
deleted file mode 100644
index ce09dff..0000000
--- a/code/handler/GivecreditHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class GivecreditHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("GivecreditHandler")
diff --git a/code/handler/HelpmessageHandler.py b/code/handler/HelpmessageHandler.py
deleted file mode 100644
index 7c906bb..0000000
--- a/code/handler/HelpmessageHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class HelpmessageHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("HelpmessageHandler")
diff --git a/code/handler/HistoryHandler.py b/code/handler/HistoryHandler.py
index 38cbd69..8e79d2b 100644
--- a/code/handler/HistoryHandler.py
+++ b/code/handler/HistoryHandler.py
@@ -1,7 +1,36 @@
+# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web
import tornado.httpserver
-import os,dbapi
+from tornado.escape import *
+import json
+
class HistoryHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("HistoryHandler")
+ def get(self):
+ self.write("historyHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content='{"name":"test3"}'
+ jobj=json.loads(content)
+ user = self.application.dbapi.getUserByUserName(jobj['username'])
+ if(user is None):
+ self.write('{"state":2,"decs":"User not exist"}')
+ return
+ uid = user['id']
+ events=self.application.dbapi.getEventsByUserId(uid)
+ for item in events:
+ item['longitude'] = float(item['longitude'])
+ item['latitude'] = float(item['latitude'])
+ item['starttime'] = item['starttime'].strftime('%Y-%m-%d %H:%M:%S')
+ if(item['endtime'] is None):
+ item['endtime'] = ""
+ else:
+ item['endtime'] = item['endtime'].strftime('%Y-%m-%d %H:%M:%S')
+ #result=self.application.dbapi.getEventsByUserName(jobj['name'])
+ supports = self.application.dbapi.getSupportsbyUid(uid)
+ for item in supports:
+ item['time'] = item['time'].strftime('%Y-%m-%d %H:%M:%S')
+ print json_encode(events),json_encode(supports)
+ self.write('{"state":1,"events":'+json_encode(events)+',"supports":'+json_encode(supports)+'}')
+ return
diff --git a/code/handler/LoginHandler.py b/code/handler/LoginHandler.py
deleted file mode 100644
index bf9c90b..0000000
--- a/code/handler/LoginHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class LoginHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("login")
diff --git a/code/handler/LogoutHandler.py b/code/handler/LogoutHandler.py
deleted file mode 100644
index 212d295..0000000
--- a/code/handler/LogoutHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class LogoutHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("LogoutHandler")
diff --git a/code/handler/QuitaidHandler.py b/code/handler/QuitaidHandler.py
deleted file mode 100644
index 83434c6..0000000
--- a/code/handler/QuitaidHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class QuitaidHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("QuitaidHandler")
diff --git a/code/handler/RegisterHandler.py b/code/handler/RegisterHandler.py
deleted file mode 100644
index ca1f57f..0000000
--- a/code/handler/RegisterHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class RegisterHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("RegisterHandler")
diff --git a/code/handler/RelativesHandler.py b/code/handler/RelativesHandler.py
new file mode 100644
index 0000000..c6ac8a3
--- /dev/null
+++ b/code/handler/RelativesHandler.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+'''Yeqin Zheng, 09/07/2014'''
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+from tornado.escape import *
+import json
+
+''' Add a relation between two users. Succeed with "1" returned, else with "0". '''
+
+class AddrelativesHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("AddrelativesHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"u_name":"test1","r_name":"test5","info":"i am",'kind':}'
+ j = json.loads(content)
+ row = self.application.dbapi.getRelationByUsername(j['u_name'], j['r_name'])
+ if row == 0:
+ self.application.dbapi.addtempRelationByUsername(j['u_name'], j['r_name'],j['kind'],j['info'])
+ #push data
+ cid = self.application.dbapi.getUserByUserName(j['r_name'])['cid']
+ pushdata = {}
+ datainside = {}
+ pushdata['type'] = "invite"
+ datainside['username'] = j['u_name']
+ datainside['info'] = j['info']
+ datainside['type'] = j['kind']
+ pushdata['data'] = datainside
+ self.application.push.pushToSingle(cid,json_encode(pushdata))
+ add_message = {'state': 1}
+ print "add relative success"
+ else:
+ add_message = {'state': 0}
+ print "two already has relative relation"
+ self.write(add_message)
+ return
+
+class CheckrelativesHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("CheckrelativesHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"test1"}'
+ j = json.loads(content)
+ userid=self.application.dbapi.getUserByUserName(j['username'])["id"]
+ re=self.application.dbapi.CheckRelationbyId(userid)
+ if re!=():
+ relatives=[]
+ for row in re:
+ info=self.application.dbapi.getUsermessegeByUserId(row["cid"])
+ info['kind'] = row['kind']
+ info['avatar'] = self.application.util.getAvatarbyUid(info['id'])
+ #relatives.append('{"info":'+str(info)+',"avatar":'+self.application.util.getAvatarbyUid(info['id'])+'}')
+ relatives.append(info)
+ data={'state':1,'relatives':relatives}
+ else:
+ data={'state':1,'relatives':'[]'}
+ self.write(json_encode(data))
+
+'''Yeqin Zheng, 09/07/2014'''
+''' Delete a relation between two users. Succeed with "1" returned, else with "0". '''
+class DeleterelativesHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("DeleterelativesHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username1":"ooo","username2":"11oo"}'
+ j = json.loads(content)
+ row = self.application.dbapi.getRelationByUsername(j['username1'],j['username2'])
+ if row == 0 :
+ delete_message = {'state': 0}
+ print "two has no relations"
+ else :
+ self.application.dbapi.deleteRelationByUsername(j['username1'],j['username2'])
+ print "delete relations success"
+ delete_message = {'state': 1}
+
+ self.write(delete_message)
+ return
+
+class AgreerelativesHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("AgreerelativesHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"u_name":"ooo","c_name":"11oo","kind": ,"agree":1(1同意,0不同意)}'
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['u_name'])
+ cid = self.application.dbapi.getUserByUserName(j['c_name'])['id']
+ if(j['agree'] == "1"):
+ self.application.dbapi.deletetemprelation(user['id'],cid)
+ self.application.dbapi.addRelationByUid(user['id'],cid,j['kind'])
+ print "agree 1"
+ pushdata = {}
+ pushdata['type'] = "agree"
+ data = {}
+ data['userid'] = user['id']
+ data['username'] = user['name']
+ data['type'] = j['kind']
+ self.application.push.pushToSingle(user['cid'],json_encode(pushdata))
+ state = {'state':1}
+ else:
+ self.application.dbapi.deletetemprelationwithkind(user['id'],cid,j['kind'])
+ print "agree 0"
+ state = {'state':1}
+ self.write(json_encode(state))
+ return
+
+class ValidationHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("ValidationHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"test6"}'
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ validations = self.application.dbapi.gettemprelationbyCid(user['id'])
+ result={}
+ if len(validations):
+ result['state'] = 1
+ for item in validations:
+ print item
+ item['u_name'] = self.application.dbapi.getUserByUserId(item['uid'])['name']
+ else:
+ result['state'] = 0
+ result['validations'] = validations
+ self.write(json_encode(result))
+ return
diff --git a/code/handler/SendsupportHandler.py b/code/handler/SendsupportHandler.py
deleted file mode 100644
index 19d6d73..0000000
--- a/code/handler/SendsupportHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class SendsupportHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("SendsupportHandler")
diff --git a/code/handler/SupportmessageHandler.py b/code/handler/SupportmessageHandler.py
deleted file mode 100644
index 9fd7c28..0000000
--- a/code/handler/SupportmessageHandler.py
+++ /dev/null
@@ -1,7 +0,0 @@
-import tornado.ioloop
-import tornado.web
-import tornado.httpserver
-import os,dbapi
-class SupportmessageHandler(tornado.web.RequestHandler):
- def post(self):
- self.write("SupportmessageHandler")
diff --git a/code/handler/ThirdPartHandlers.py b/code/handler/ThirdPartHandlers.py
new file mode 100644
index 0000000..91742da
--- /dev/null
+++ b/code/handler/ThirdPartHandlers.py
@@ -0,0 +1,165 @@
+# coding: utf-8
+# Filename: handlers.py
+__author__ = 'Administrator'
+
+import tornado.web
+import json,os,base64
+import urllib
+from CHRequestHandler import CHRequestHandler, LackParamsException, NoUserException
+
+# 2014-07-17
+#
+# post: access_token, platform
+# return: result
+# actions:
+# visit get_token_info
+# check for binding
+# create new user
+# bind user
+# update user state
+# 我需要与前后台协商,除了本地登录之外,在增加第三方专用的返回值。这里就将就一下
+# error code
+# 50001 访问授权api失败
+# 50002 不支持的平台
+# 50003 授权过期
+class ThirdPartyLoginHandler(CHRequestHandler):
+ platformapi = { "sinaweibo": "https://api.weibo.com/oauth2/get_token_info" }
+ requestname = "thirdpartylogin"
+
+ def post(self):
+ try:
+ j = self.getParams(["platformname", "access_token", "latitude", "longitude"])
+ except LackParamsException:
+ self.writeError(1, ThirdPartyLoginHandler.requestname)
+ return
+ url = ThirdPartyLoginHandler.platformapi.get(j["platformname"])
+ if url is None:
+ self.writeError(50002, ThirdPartyLoginHandler.requestname)
+ return
+ data = "access_token=" + j["access_token"]
+ try:
+ resultstr = urllib.urlopen(url, data).read()
+ except IOError:
+ self.writeError(50001, ThirdPartyLoginHandler.requestname)
+ return
+ # 解析返回值,这里依旧只考虑了新浪微博
+ result = json.loads(resultstr)
+ expire_in = result["expire_in"]
+ # 如果令牌超时,则驳回请求
+ if expire_in <= 0:
+ # 返回state:1
+ self.writeError(50003, ThirdPartyLoginHandler.requestname)
+ return
+ # 第三方不需要在本系统中设置用户名,因此自动生成一个作为第三方用户的唯一标识
+ username = "*" + j["platformname"] + ("%i" % result["uid"])
+ # 这里做简单处理:直接将星号+platform+uid作为用户名,不设密码
+ # 其他用户不允许第一个符号是星号。一般的用户名只允许出现字母,数字,空格,和下划线。
+ # 首先检查是否已经注册过
+ try:
+ uid = self.getUserId(username)
+ except NoUserException:
+ newUser = {"username": username,
+ "kind": 1,
+ "password": "",
+ "cardid": 0,
+ "realname": "",
+ "sex": 0,
+ "age": 0,
+ "address": "",
+ "phone": "",
+ "vocation": 3,
+ "illness": ""}
+ uid = self.application.dbapi.register(newUser)
+ avatar=open(os.path.abspath('./static/avatar/default.png'),"rb");
+ filestring=base64.standard_b64encode(avatar.read())
+ self.application.util.setAvatarbyUid(uid,filestring)
+ self.application.score.userRegister(uid,self.application.dbapi)
+ self.application.dbapi.updateUseLBS(j['latitude'],j['longitude'],uid)
+ self.application.dbapi.updateUserstate(uid, 1) # 登录状态为数字1
+ self.writeOK()
+ return
+
+# 在第三方登录成功之后,第三方用户状态就与本地用户相同了。这里的登出过程也几乎没有区别
+class ThirdPartyLogoutHandler(tornado.web.RequestHandler):
+ # 数据库的所有操作都没有进行用户是否已经登录的检查。
+ # 鉴于这种检查时普遍操作,可能会作为任何一项需要特权的操作的前置操作,仅仅需要修改少数类,因此这里不做检查,等待小组长修复该bug
+ # 这里需要将访问方式改为post。之前考虑失误。显然应该是post
+ def post(self):
+ # 这与正常的登出一模一样。直接copy代码。
+ # 这里用到了username。按照我的预想,是不需要username的。但是第一版可以简单设计。
+ # 这需要我修改几处anroid代码
+ # 其他人采用json格式传输数据。我这里并没有采用,而是直接使用参数传递。
+ username = "*" + self.get_argument("platform") + self.get_argument("uid")
+ print("username: " + username)
+ # 因为假设所有的特权操作都经过了检查,因此不必考虑用户不存在的情况
+ record = self.application.dbapi.getUserByUserName(username)
+ uid = record["id"]
+ self.application.dbapi.updateUserstate(uid, 0)
+ self.write("{'state':1}")
+ self.write("Third Party Logout Test")
+
+# 50001 访问平台授权服务器错误
+# 50002 不支持的平台
+# 50003 授权超时
+class ThirdPartyRemoveAccountHandler(CHRequestHandler):
+ platformapi = { "sinaweibo": "https://api.weibo.com/oauth2/get_token_info" }
+ requestname = "thirdpartyremoveaccount"
+
+ # 与前面一个一样,这里的get也是不对的,需要改为post
+ def post(self):
+ try:
+ j = self.getParams(["platformname", "access_token"])
+ except LackParamsException:
+ self.writeError(1, ThirdPartyLoginHandler.requestname)
+ return
+ url = ThirdPartyLoginHandler.platformapi.get(j["platformname"])
+ if url is None:
+ self.writeError(50002, ThirdPartyLoginHandler.requestname)
+ return
+ data = "access_token=" + j["access_token"]
+ try:
+ resultstr = urllib.urlopen(url, data).read()
+ except IOError:
+ self.writeError(50001, ThirdPartyLoginHandler.requestname)
+ return
+ # 解析返回值,这里依旧只考虑了新浪微博
+ result = json.loads(resultstr)
+ expire_in = result["expire_in"]
+ # 如果令牌超时,则驳回请求
+ if expire_in <= 0:
+ # 返回state:1
+ self.writeError(50003, ThirdPartyLoginHandler.requestname)
+ return
+ # 第三方不需要在本系统中设置用户名,因此自动生成一个作为第三方用户的唯一标识
+ username = "*" + j["platformname"] + ("%i" % result["uid"])
+ # 这里做简单处理:直接将星号+platform+uid作为用户名,不设密码
+ # 其他用户不允许第一个符号是星号。一般的用户名只允许出现字母,数字,空格,和下划线。
+ # 首先检查是否已经注册过
+ try:
+ uid = self.getUserId(username)
+ except NoUserException:
+ self.writeError(2, ThirdPartyRemoveAccountHandler.requestname)
+ return
+ self.application.dbapi.cancelUser(uid)
+ # 用户已删除,这是返回登录成功的返回值,暗示了用户已删除
+ print("delete user")
+ self.writeOK()
+
+class ThirdPartyFillUserInfoHandler(tornado.web.RequestHandler):
+ def post(self):
+ username = "*" + self.get_argument("platform") + self.get_argument("uid")
+ newUserInfo = {
+ "sex": self.get_argument("sex"),
+ "address": self.get_argument("address")
+ }
+ user = self.application.dbapi.getUserByUserName(username)
+ if(user is None):
+ self.write("{'state':1}")
+ print "username not exist"
+ return
+ print("username: " + username)
+ print("sex: " + newUserInfo["sex"])
+ print("address: " + newUserInfo["address"])
+ result = self.application.dbapi.updateUserinfo(user['id'], newUserInfo)
+ self.write("{'result':"+ str(result)+"}")
+ print("UpdateUserInfo success")
diff --git a/code/handler/UserHandler.py b/code/handler/UserHandler.py
new file mode 100644
index 0000000..9e35881
--- /dev/null
+++ b/code/handler/UserHandler.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+from tornado.escape import *
+import json,os,base64
+
+class RegisterHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("RegisterHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username": "test1","password": "1","kind": 1, "cardid":"test" ,"realname":"1","sex":1,"age":1, "address":"1","illness":"1","phone":"11"}'
+ j = json.loads(content)
+ if(self.application.dbapi.getUserByUserName(j['username']) is not None):
+ self.write("{'state':1}")
+ print "username exist"
+ return
+ if(self.application.dbapi.getInfoBycardid(j['cardid']) is not None):
+ self.write("{'state':2}")
+ print "cardid exist"
+ return
+ uid = self.application.dbapi.register(j)
+ self.write("{'state':3}")
+ print("Register success")
+
+ if('file' in j):
+ self.application.util.setAvatar(j['username'],j['file'],self.application.dbapi)
+ else:
+ avatar=open(os.path.abspath('./static/avatar/default.png'),"rb");
+ filestring=base64.standard_b64encode(avatar.read())
+ self.application.util.setAvatar(j['username'],filestring,self.application.dbapi)
+ self.application.score.userRegister(uid,self.application.dbapi)
+ return
+
+class LoginHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("LoginHandler
")
+
+ def post(self):
+ content = self.request.body
+ #content = '{"username":"12","password":"1","latitude":23.000000,"longitude":23.000000}'
+ j = json.loads(content)
+ if(j['username'].strip()=='' or j['username'].strip()[0]== '*'):
+ self.write("{'state':1}")
+ print "username is illegal"
+ return
+
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is None):
+ self.write("{'state':1}")
+ print "username not exist"
+ return
+ if(user["password"]!= j['password']):
+ self.write("{'state':2}")
+ print "passwd incorrect"
+ return
+ if("latitude" in j):
+ self.application.dbapi.updateUseLBS(j['latitude'],j['longitude'],user['id'])
+ self.application.dbapi.updateUserstate(user['id'],1)
+ result = {}
+ result['state'] = 3
+ result['userid'] = user['id']
+ self.write(json_encode(result))
+ print("Login success")
+ self.application.score.userLogin(user['id'],self.application.dbapi)
+ return
+
+class UpdateCid(tornado.web.RequestHandler):
+ def get(self):
+ self.write("UpdateCid
")
+
+ def post(self):
+ content = self.request.body
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is None):
+ self.write("{'state':2}")
+ print "username not exist"
+ return
+ self.application.dbapi.UpdateCidByuid(j['cid'],user['id'])
+ self.write("{'state':1}")
+ print("Login success")
+ return
+
+class LogoutHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("LogoutHandler
")
+
+ def post(self):
+ content =self.request.body
+ print content
+ #content = '{"username":"11oo"}'
+ j = json.loads(content)
+ uid = self.application.dbapi.getUserByUserName(j['username'])['id']
+ self.application.dbapi.updateUserstate(uid,0)
+ self.write("{'state':1}")
+ print("Logout success")
+ self.application.score.checkOnlineHours(uid,self.application.dbapi)
+ return
+
+class AuthenHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("AuthenHandler
")
+
+ def post(self):
+ #self.write("AuthenHandler")
+ print "start"
+ content='{"username":"test1","message":{"kind":1}}'
+ jobj=json.loads(content)
+ askuser = self.application.dbapi.getUserInfobyName(jobj["username"])
+ print self.application.dbapi.getAroundbyvocationOrKind(askuser["longitude"],askuser["latitude"],1,5,10,5)
+ #print askuser
+ aroundhelpers = self.application.dbapi.getUserAroundbykind(askuser["longitude"],askuser["latitude"],5,jobj['message']['kind'])
+ #print aroundhelpers
+ friendlist = self.application.dbapi.getRelativesIdbyUid(askuser['id'])
+ #print friendlist
+ hashelpaskuserlist = self.application.dbapi.getHelpersIdbyUid(askuser['id'])
+ #print hashelpaskuserlist
+ pushlist = self.application.util.getPushlistByCredit(askuser,aroundhelpers,friendlist,hashelpaskuserlist,0.2,self.application.dbapi)
+ #print pushlist
+ print "lall"
+ return
+
+
+class CancelHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("CancelHandler
")
+
+ def post(self):
+ content = self.request.body
+ print content
+ #content = '{"username":"test","password":"test"}'
+ j = json.loads(content)
+ if(j['username'].strip()=='' ):
+ self.write("{'state':1}")
+ print "username is null"
+ return
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is None):
+ self.write("{'state':1}")
+ print "username not exist,can not cancel"
+ return
+ if(user["password"]!= j['password']):
+ self.write("{'state':2}")
+ print "passwd incorrect,can not cancel"
+ return
+ self.application.dbapi.cancelUser(user['id'])
+ self.write("{'state':3}")
+ print("cancel success")
+ return
+
+class SearchHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("SearchHandler
")
+
+ def post(self):
+ content =self.request.body
+ print content
+ #content = '{"searchtype":"2","fromage":"20","endage":"30"}'
+ j = json.loads(content)
+ if(j['searchtype'] == "exactSearch"):
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is not None):
+ users = []
+ username = {}
+ username['username'] = user['name']
+ users.append(username)
+ result ={}
+ result['state'] = 1
+ result['users'] = users
+ else:
+ result = {'state': 0}
+ elif(j['searchtype'] == "keywordSearch"):
+ result = self.application.dbapi.searchUserbySexAgeKind(j)
+ else:
+ result = self.application.dbapi.getUserAround(j['longitude'],j['latitude'],5)
+ print result
+ self.write(json_encode(result))
+ print("Login success")
+ return
+
+class GetAvatarHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("CancelHandler
")
+
+ def post(self):
+ content =self.request.body
+ print content
+ #content = '{"uid":"test","username":"testname"}'
+ j = json.loads(content)
+ result = {}
+ if('uid' in j):
+ result['avatar'] = self.application.util.getAvatarbyUid(j['uid'])
+ else:
+ result['avatar'] = self.application.util.getAvatar(j['username'],self.application.dbapi)
+ self.write(json_encode(result))
+ return
diff --git a/code/handler/UserInfoHandler.py b/code/handler/UserInfoHandler.py
new file mode 100644
index 0000000..16b95de
--- /dev/null
+++ b/code/handler/UserInfoHandler.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+import tornado.ioloop
+import tornado.web
+import tornado.httpserver
+from tornado.escape import *
+import json
+
+class UpdateUserInfoHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("UpdateUserInfoHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"dasda1","changemessage":{"age":15,"illness":"我是小啊小苹果"}}'
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is None):
+ self.write("{'state':1}")
+ print "username not exist"
+ return
+ if('avatar' in j):
+ self.application.util.setAvatar(j['username'],j['avatar'],self.application.dbapi)
+ result = self.application.dbapi.updateUserinfo(user['id'],j['changemessage'])
+ if(isinstance(result,list)):
+ state = 1
+ else:
+ state =2
+ self.write("{'state':"+ str(state)+"}")
+ print("UpdateUserInfo success")
+ return
+
+class GetUserInfoHandler(tornado.web.RequestHandler):
+ def get(self):
+ self.write("GetUserInfoHandler
")
+
+ def post(self):
+ content =self.request.body
+ #content = '{"username":"test1"}'
+ j = json.loads(content)
+ user = self.application.dbapi.getUserByUserName(j['username'])
+ if(user is None):
+ self.write("{'state':1}")
+ print "username not exist"
+ return
+ result = self.application.dbapi.getUsermessegeByUserId(user['id'])
+ result['credit'] = 5 * result['credit']
+ scorelimit = self.application.score.getRankByScore(result['score'])
+
+ result['scoreMin'] = scorelimit['scoreMin']
+ result['scoreMax'] = scorelimit['scoreMax']
+ result['scoreLevel'] = scorelimit['scoreLevel']
+ print result
+ self.write("{'result':"+ json_encode(result)+"}")
+ print("GetUserInfo success")
+ return
diff --git a/code/handler/__init__.py b/code/handler/__init__.py
index 9540260..b8fad30 100644
--- a/code/handler/__init__.py
+++ b/code/handler/__init__.py
@@ -1,16 +1,10 @@
-__all__ = ["RegisterHandler",
- "LoginHandler",
- "AuthenHandler",
- "LogoutHandler",
- "CancelHandler",
- "CheckrelativesHandler",
- "DeleterelativesHandler",
- "AddrelativesHandler",
- "HistoryHandler",
- "HelpmessageHandler",
- "SupportmessageHandler",
- "FinishHandler",
- "GivecreditHandler",
- "AddaidHandler",
- "SendsupportHandler",
- "QuitaidHandler"]
+__all__ = [
+ "UserHandler",
+ "RelativesHandler",
+ "HistoryHandler",
+ "EventHandler",
+ "UserInfoHandler",
+ "FollowHandler",
+ "GetArroundEvent",
+ "ThirdPartHandlers",
+ "Authorize"]
diff --git a/code/handler/xmltojson.py b/code/handler/xmltojson.py
new file mode 100644
index 0000000..6c5336a
--- /dev/null
+++ b/code/handler/xmltojson.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+#python xml.etree.ElementTree
+
+import os
+import xml.etree.ElementTree as ET
+from xml.dom import minidom
+
+class xmltojson:
+ #global var
+ #show log
+ SHOW_LOG = True
+ #XML file
+ XML_PATH = None
+ a={}
+ m=[]
+
+ def get_root(self,path):
+ '''parse the XML file,and get the tree of the XML file
+ finally,return the root element of the tree.
+ if the XML file dose not exist,then print the information'''
+ #if os.path.exists(path):
+ #if SHOW_LOG:
+ #print('start to parse the file : [{}]'.format(path))
+ tree = ET.fromstring(path)
+ return tree
+ #else:
+ #print('the path [{}] dose not exist!'.format(path))
+
+ def get_element_tag(self,element):
+ '''return the element tag if the element is not None.'''
+ if element is not None:
+
+ return element.tag
+ else:
+ print('the element is None!')
+
+ def get_element_attrib(self,element):
+ '''return the element attrib if the element is not None.'''
+ if element is not None:
+
+ return element.attrib
+ else:
+ print('the element is None!')
+
+ def get_element_text(self,element):
+ '''return the text of the element.'''
+ if element is not None:
+ return element.text
+ else:
+ print('the element is None!')
+
+ def get_element_children(self,element):
+ '''return the element children if the element is not None.'''
+ if element is not None:
+
+ return [c for c in element]
+ else:
+ print('the element is None!')
+
+ def get_elements_tag(self,elements):
+ '''return the list of tags of element's tag'''
+ if elements is not None:
+ tags = []
+ for e in elements:
+ tags.append(e.tag)
+ return tags
+ else:
+ print('the elements is None!')
+
+ def get_elements_attrib(self,elements):
+ '''return the list of attribs of element's attrib'''
+ if elements is not None:
+ attribs = []
+ for a in elements:
+ attribs.append(a.attrib)
+ return attribs
+ else:
+ print('the elements is None!')
+
+ def get_elements_text(self,elements):
+ '''return the dict of element'''
+ if elements is not None:
+ text = []
+ for t in elements:
+ text.append(t.text)
+ return dict(zip(self.get_elements_tag(elements), text))
+ else:
+ print('the elements is None!')
+
+
+
+ def main(self,xml):
+
+ #root
+ root = self.get_root(xml)
+
+ #children
+ children = self.get_element_children(root)
+
+ children_tags = self.get_elements_tag(children)
+
+ children_attribs = self.get_elements_attrib(children)
+
+ i=0
+
+ #获取二级元素的每一个子节点的名称和值
+ for c in children:
+ p=0
+ c_children = self.get_element_children(c)
+ dict_text = self.get_elements_text(c_children)
+ if dict_text :
+ if children_tags[i] =='TemplateSMS':
+ self.a['templateSMS']=dict_text
+ else :
+ if children_tags[i]=='SubAccount':
+ k=0
+
+ for x in children:
+ if children_tags[k]=='totalCount':
+ self.m.append(dict_text)
+ self.a['SubAccount']=self.m
+ p=1
+ k=k+1
+ if p==0:
+ self.a[children_tags[i]]=dict_text
+ else:
+ self.a[children_tags[i]]=dict_text
+
+
+ else:
+ self.a[children_tags[i]]=c.text
+ i=i+1
+ return self.a
+
diff --git a/code/index.html b/code/index.html
deleted file mode 100644
index 34ff401..0000000
--- a/code/index.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
- Test
-
-
-
-
-
- /api/addrelatives
-
-
- /api/deleterelatives
-
-
- /api/addaid
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/code/main.py b/code/main.py
index 2ccc35d..3528967 100644
--- a/code/main.py
+++ b/code/main.py
@@ -1,39 +1,10 @@
import tornado.ioloop
import tornado.web
import tornado.httpserver
-import os,MySQLdb,dbapi
+import os,MySQLdb,dbapi,util,score
from handler import *
-
-#Change the handler class and make it to fit your requirement
-#class historyHandler(tornado.web.RequestHandler):
-# def get(self):
-# self.render("index.html")
-
-# def post(self):
-# username=self.get_argument("username")
-# print self.application.dbapi.getEventById(1)
-
-#register url handler
-#class RegisterHandler(tornado.web.RequestHandler):
-# def post(self):
- #content = self.get_argument("content")
-# content = '{"username": "haha","password": 111111,"kind": 1, "cardid":11301 ,"realname":"hiii","sex":1,"age":41, "address":"iii","illness":"hijiiii"}'
-# j = json.loads(content)
-# if(self.application.dbapi.hasuserName(j['username'])):
-# return {'state':1}
-# if(self.application.dbapi.hascardid(j['cardid'])):
-# return {'state':2}
-# self.application.dbapi.regist(j)
-# return {'state':3}
-
-#login url handler
-class IndexHandler(tornado.web.RequestHandler):
- def get(self):
- self.render("index.html")
-
-#class authentication
-
-
+from push import *
+from xml.dom.minidom import parse,parseString
class app(tornado.web.Application):
def __init__(self):
@@ -41,26 +12,55 @@ def __init__(self):
"static_path": os.path.join(os.path.dirname(__file__), "static"),
"debug": True
}
- handlers=[(r"/",IndexHandler),
- (r"/api/login",LoginHandler.LoginHandler),
- (r"/api/register",RegisterHandler.RegisterHandler),
- (r"/api/userauthentication",AuthenHandler.AuthenHandler),
- (r"/api/logout",LogoutHandler.LogoutHandler),
- (r"/api/cancel",CancelHandler.CancelHandler),
- (r"/api/checkrelatives",CheckrelativesHandler.CheckrelativesHandler),
- (r"/api/deleterelatives",DeleterelativesHandler.DeleterelativesHandler),
- (r"/api/addrelatives",AddrelativesHandler.AddrelativesHandler),
- (r"/api/history",HistoryHandler.HistoryHandler),
- (r"/api/helpmessage",HelpmessageHandler.HelpmessageHandler),
- (r"/api/supportmessage",SupportmessageHandler.SupportmessageHandler),
- (r"/api/finish",FinishHandler.FinishHandler),
- (r"/api/givecredit",GivecreditHandler.GivecreditHandler),
- (r"/api/addaid",AddaidHandler.AddaidHandler),
- (r"/api/sendsupport",SendsupportHandler.SendsupportHandler),
- (r"/api/quitaid",QuitaidHandler.QuitaidHandler)
- ]
+ handlers=[
+ (r"/api/login",UserHandler.LoginHandler),
+ (r"/api/register",UserHandler.RegisterHandler),
+ (r"/api/userauthentication",UserHandler.AuthenHandler),
+ (r"/api/logout",UserHandler.LogoutHandler),
+ (r"/api/cancel",UserHandler.CancelHandler),
+ (r"/api/updatecid",UserHandler.UpdateCid),
+ (r"/api/search",UserHandler.SearchHandler),
+ (r"/api/getavatar",UserHandler.GetAvatarHandler),
+
+ (r"/api/checkrelatives",RelativesHandler.CheckrelativesHandler),
+ (r"/api/deleterelatives",RelativesHandler.DeleterelativesHandler),
+ (r"/api/addrelatives",RelativesHandler.AddrelativesHandler),
+ (r"/api/agreerelatives",RelativesHandler.AgreerelativesHandler),
+ (r"/api/getvalidation",RelativesHandler.ValidationHandler),
+
+ (r"/api/history",HistoryHandler.HistoryHandler),
+
+ (r"/api/helpmessage",EventHandler.HelpmessageHandler),
+ (r"/api/supportmessage",EventHandler.SupportmessageHandler),
+ (r"/api/finish",EventHandler.FinishHandler),
+ (r"/api/givecredit",EventHandler.GivecreditHandler),
+ (r"/api/addaid",EventHandler.AddaidHandler),
+ (r"/api/sendsupport",EventHandler.SendsupportHandler),
+ (r"/api/quitaid",EventHandler.QuitaidHandler),
+ (r"/api/event",EventHandler.EventHandler),
+
+ (r"/api/getuserinfo",UserInfoHandler.GetUserInfoHandler),
+ (r"/api/updateuserinfo",UserInfoHandler.UpdateUserInfoHandler),
+
+ (r"/api/getAround",GetArroundEvent.GetArroundEvent),
+
+ (r"/api/startfollow",FollowHandler.startFollowHandler),
+ (r"/api/cancelfollow",FollowHandler.cancelFollowHandler),
+
+ (r"/api/thirdpartylogin",ThirdPartHandlers.ThirdPartyLoginHandler),
+ (r"/api/thirdpartyremoveaccount",ThirdPartHandlers.ThirdPartyRemoveAccountHandler),
+ (r"/api/thirdpartyfilluserinfo",ThirdPartHandlers.ThirdPartyFillUserInfoHandler),
+
+ (r"/api/authstate", Authorize.AuthStateHandler),
+ (r"/api/requestemailauth", Authorize.RequestEmailAuthHandler),
+ (r"/api/authemail", Authorize.AuthEmailHandler),
+ (r"/api/requestphoneauth", Authorize.RequestPhoneAuthHandler),
+ (r"/api/authphone", Authorize.AuthPhoneHandler)]
tornado.web.Application.__init__(self,handlers,**settings)
self.dbapi=dbapi.dbapi()
+ self.util=util.util()
+ self.push = Push()
+ self.score=score.score()
if __name__=="__main__":
diff --git a/code/push/__init__.py b/code/push/__init__.py
new file mode 100644
index 0000000..a32bd9d
--- /dev/null
+++ b/code/push/__init__.py
@@ -0,0 +1,92 @@
+__all__=["Push"]
+
+from igt_push import *
+from igetui.template import *
+from igetui.template.igt_base_template import *
+from igetui.template.igt_transmission_template import *
+from igetui.template.igt_link_template import *
+from igetui.template.igt_notification_template import *
+from igetui.template.igt_notypopload_template import *
+from igetui.igt_message import *
+from igetui.igt_target import *
+from igetui.template import *
+
+class Push:
+
+ __APPKEY = "r3Gm2zkRsb8QLMq2U92Bi8"
+ __APPID = "0yZq9kruSq8zvSpYB2UiA1"
+ __MASTERSECRET = "h8Ppk4heNR6MACNWjN3XB2"
+ __HOST = 'http://sdk.open.api.igexin.com/apiex.htm'
+
+
+ __TEMPLATE = TransmissionTemplate()
+
+ def __init__(self):
+
+ self.__TEMPLATE = TransmissionTemplate()
+ self.__TEMPLATE.transmissionType = 2
+ self.__TEMPLATE.appId = self.__APPID
+ self.__TEMPLATE.appKey = self.__APPKEY
+
+ def pushToSingle(self, CID, content):
+ push = IGeTui(self.__HOST, self.__APPKEY, self.__MASTERSECRET)
+
+ self.__TEMPLATE.transmissionContent = content
+
+ message = IGtSingleMessage()
+ message.isOffline = True
+ message.offlineExpireTime = 1000 * 3600 * 12
+ message.data = self.__TEMPLATE
+
+ target = Target()
+ target.appId = self.__APPID
+ target.clientId = CID
+
+ ret = push.pushMessageToSingle(message, target)
+ return ret
+
+ def pushToList(self, CIDList, content, details=False):
+ push = IGeTui(self.__HOST, self.__APPKEY, self.__MASTERSECRET)
+
+ self.__TEMPLATE.transmissionContent = content
+
+ os.environ['needDetails'] = 'true' if details else 'false'
+
+ message = IGtListMessage()
+ message.data = self.__TEMPLATE
+ message.isOffline = True
+ message.offlineExpireTime = 1000 * 3600 * 12
+
+ targets = [];
+
+ for index in range(len(CIDList)):
+ target = Target()
+ target.appId = self.__APPID
+ target.clientId = CIDList[index]
+ targets.append(target)
+
+ contentId = push.getContentId(message)
+ ret = push.pushMessageToList(contentId, targets)
+ return ret
+
+ def pushToAll(self, content):
+ push = IGeTui(self.__HOST, self.__APPKEY, self.__MASTERSECRET)
+
+ self.__TEMPLATE.transmissionContent = content
+
+ message = IGtAppMessage()
+ message.data = self.__TEMPLATE
+ message.isOffline = True
+ message.offlineExpireTime = 1000 * 3600 * 12
+ message.appIdList.extend([self.__APPID])
+
+ ret = push.pushMessageToApp(message)
+ return ret
+
+ def getUserStatus(self, CID):
+ push = IGeTui(self.__HOST, self.__APPKEY, self.__MASTERSECRET)
+ return push.getClientIdStatus(self.__APPID, CID)
+
+ def stopTask(self):
+ push = IGeTui(self.__HOST, self.__APPKEY, self.__MASTERSECRET)
+ return push.stop("OSA-0226_50RYYPFmos9eQEHZrkAf27")
diff --git a/code/push/get_push_result.py b/code/push/get_push_result.py
new file mode 100644
index 0000000..ce3223c
--- /dev/null
+++ b/code/push/get_push_result.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+#数据将在30分钟之后提供查询
+#最后更新时间为2013.10.22
+import hashlib
+import urllib, urllib2, json
+def getPushResult(url,appKey,masterSecret,taskId):
+ params = {}
+ params["action"] = "getPushMsgResult"
+ params["appkey"] = appKey
+ params["taskId"] = taskId
+ sign = createSign(params,masterSecret)
+ params["sign"] = sign
+ rep = httpPost(url,params)
+ return rep
+def createSign(params,masterSecret):
+ sign = masterSecret
+ for (k,v) in params.items():
+ sign = sign+k+v
+ return hashlib.md5(sign).hexdigest()
+def httpPost(url, params):
+ data_json = json.dumps(params)
+ req = urllib2.Request(url, data_json)
+ res_stream = urllib2.urlopen(req, timeout = 60)
+ page_str = res_stream.read()
+ page_dict = eval(page_str)
+ return page_dict
+rep = getPushResult("http://sdk.open.api.igexin.com/api.htm","tpDVam96sY8pxhwBupJ462","TBokfpttQJ6aHIhBE9y867","GT_1017_gJs4GvJxZV77gdgBKsuvO9")
+print rep
+
+
+
diff --git a/code/push/google/__init__.py b/code/push/google/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/code/push/google/__init__.py
@@ -0,0 +1 @@
+
diff --git a/template/static/tornado_static_path b/code/push/google/protobuf/__init__.py
similarity index 100%
rename from template/static/tornado_static_path
rename to code/push/google/protobuf/__init__.py
diff --git a/code/push/google/protobuf/compiler/__init__.py b/code/push/google/protobuf/compiler/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/code/push/google/protobuf/compiler/plugin_pb2.py b/code/push/google/protobuf/compiler/plugin_pb2.py
new file mode 100644
index 0000000..77cc07a
--- /dev/null
+++ b/code/push/google/protobuf/compiler/plugin_pb2.py
@@ -0,0 +1,166 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/compiler/plugin.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+
+import google.protobuf.descriptor_pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='google/protobuf/compiler/plugin.proto',
+ package='google.protobuf.compiler',
+ serialized_pb='\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"}\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xaa\x01\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a>\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\tB,\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtos')
+
+
+
+
+_CODEGENERATORREQUEST = _descriptor.Descriptor(
+ name='CodeGeneratorRequest',
+ full_name='google.protobuf.compiler.CodeGeneratorRequest',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='file_to_generate', full_name='google.protobuf.compiler.CodeGeneratorRequest.file_to_generate', index=0,
+ number=1, type=9, cpp_type=9, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='parameter', full_name='google.protobuf.compiler.CodeGeneratorRequest.parameter', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='proto_file', full_name='google.protobuf.compiler.CodeGeneratorRequest.proto_file', index=2,
+ number=15, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=101,
+ serialized_end=226,
+)
+
+
+_CODEGENERATORRESPONSE_FILE = _descriptor.Descriptor(
+ name='File',
+ full_name='google.protobuf.compiler.CodeGeneratorResponse.File',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='insertion_point', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='content', full_name='google.protobuf.compiler.CodeGeneratorResponse.File.content', index=2,
+ number=15, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=337,
+ serialized_end=399,
+)
+
+_CODEGENERATORRESPONSE = _descriptor.Descriptor(
+ name='CodeGeneratorResponse',
+ full_name='google.protobuf.compiler.CodeGeneratorResponse',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='error', full_name='google.protobuf.compiler.CodeGeneratorResponse.error', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='file', full_name='google.protobuf.compiler.CodeGeneratorResponse.file', index=1,
+ number=15, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_CODEGENERATORRESPONSE_FILE, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=229,
+ serialized_end=399,
+)
+
+_CODEGENERATORREQUEST.fields_by_name['proto_file'].message_type = google.protobuf.descriptor_pb2._FILEDESCRIPTORPROTO
+_CODEGENERATORRESPONSE_FILE.containing_type = _CODEGENERATORRESPONSE;
+_CODEGENERATORRESPONSE.fields_by_name['file'].message_type = _CODEGENERATORRESPONSE_FILE
+DESCRIPTOR.message_types_by_name['CodeGeneratorRequest'] = _CODEGENERATORREQUEST
+DESCRIPTOR.message_types_by_name['CodeGeneratorResponse'] = _CODEGENERATORRESPONSE
+
+class CodeGeneratorRequest(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _CODEGENERATORREQUEST
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+
+class CodeGeneratorResponse(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+
+ class File(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _CODEGENERATORRESPONSE_FILE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
+ DESCRIPTOR = _CODEGENERATORRESPONSE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), '\n\034com.google.protobuf.compilerB\014PluginProtos')
+# @@protoc_insertion_point(module_scope)
diff --git a/code/push/google/protobuf/descriptor.py b/code/push/google/protobuf/descriptor.py
new file mode 100644
index 0000000..b6984d7
--- /dev/null
+++ b/code/push/google/protobuf/descriptor.py
@@ -0,0 +1,713 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Descriptors essentially contain exactly the information found in a .proto
+file, in types that make this information accessible in Python.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+from push.google.protobuf.internal import api_implementation
+
+
+if api_implementation.Type() == 'cpp':
+ if api_implementation.Version() == 2:
+ from google.protobuf.internal.cpp import _message
+ else:
+ from google.protobuf.internal import cpp_message
+
+
+class Error(Exception):
+ """Base error for this module."""
+
+
+class TypeTransformationError(Error):
+ """Error transforming between python proto type and corresponding C++ type."""
+
+
+class DescriptorBase(object):
+
+ """Descriptors base class.
+
+ This class is the base of all descriptor classes. It provides common options
+ related functionaility.
+
+ Attributes:
+ has_options: True if the descriptor has non-default options. Usually it
+ is not necessary to read this -- just call GetOptions() which will
+ happily return the default instance. However, it's sometimes useful
+ for efficiency, and also useful inside the protobuf implementation to
+ avoid some bootstrapping issues.
+ """
+
+ def __init__(self, options, options_class_name):
+ """Initialize the descriptor given its options message and the name of the
+ class of the options message. The name of the class is required in case
+ the options message is None and has to be created.
+ """
+ self._options = options
+ self._options_class_name = options_class_name
+
+ # Does this descriptor have non-default options?
+ self.has_options = options is not None
+
+ def _SetOptions(self, options, options_class_name):
+ """Sets the descriptor's options
+
+ This function is used in generated proto2 files to update descriptor
+ options. It must not be used outside proto2.
+ """
+ self._options = options
+ self._options_class_name = options_class_name
+
+ # Does this descriptor have non-default options?
+ self.has_options = options is not None
+
+ def GetOptions(self):
+ """Retrieves descriptor options.
+
+ This method returns the options set or creates the default options for the
+ descriptor.
+ """
+ if self._options:
+ return self._options
+ from google.protobuf import descriptor_pb2
+ try:
+ options_class = getattr(descriptor_pb2, self._options_class_name)
+ except AttributeError:
+ raise RuntimeError('Unknown options class name %s!' %
+ (self._options_class_name))
+ self._options = options_class()
+ return self._options
+
+
+class _NestedDescriptorBase(DescriptorBase):
+ """Common class for descriptors that can be nested."""
+
+ def __init__(self, options, options_class_name, name, full_name,
+ file, containing_type, serialized_start=None,
+ serialized_end=None):
+ """Constructor.
+
+ Args:
+ options: Protocol message options or None
+ to use default message options.
+ options_class_name: (str) The class name of the above options.
+
+ name: (str) Name of this protocol message type.
+ full_name: (str) Fully-qualified name of this protocol message type,
+ which will include protocol "package" name and the name of any
+ enclosing types.
+ file: (FileDescriptor) Reference to file info.
+ containing_type: if provided, this is a nested descriptor, with this
+ descriptor as parent, otherwise None.
+ serialized_start: The start index (inclusive) in block in the
+ file.serialized_pb that describes this descriptor.
+ serialized_end: The end index (exclusive) in block in the
+ file.serialized_pb that describes this descriptor.
+ """
+ super(_NestedDescriptorBase, self).__init__(
+ options, options_class_name)
+
+ self.name = name
+ # TODO(falk): Add function to calculate full_name instead of having it in
+ # memory?
+ self.full_name = full_name
+ self.file = file
+ self.containing_type = containing_type
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def GetTopLevelContainingType(self):
+ """Returns the root if this is a nested type, or itself if its the root."""
+ desc = self
+ while desc.containing_type is not None:
+ desc = desc.containing_type
+ return desc
+
+ def CopyToProto(self, proto):
+ """Copies this to the matching proto in descriptor_pb2.
+
+ Args:
+ proto: An empty proto instance from descriptor_pb2.
+
+ Raises:
+ Error: If self couldnt be serialized, due to to few constructor arguments.
+ """
+ if (self.file is not None and
+ self._serialized_start is not None and
+ self._serialized_end is not None):
+ proto.ParseFromString(self.file.serialized_pb[
+ self._serialized_start:self._serialized_end])
+ else:
+ raise Error('Descriptor does not contain serialization.')
+
+
+class Descriptor(_NestedDescriptorBase):
+
+ """Descriptor for a protocol message type.
+
+ A Descriptor instance has the following attributes:
+
+ name: (str) Name of this protocol message type.
+ full_name: (str) Fully-qualified name of this protocol message type,
+ which will include protocol "package" name and the name of any
+ enclosing types.
+
+ containing_type: (Descriptor) Reference to the descriptor of the
+ type containing us, or None if this is top-level.
+
+ fields: (list of FieldDescriptors) Field descriptors for all
+ fields in this type.
+ fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
+ objects as in |fields|, but indexed by "number" attribute in each
+ FieldDescriptor.
+ fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
+ objects as in |fields|, but indexed by "name" attribute in each
+ FieldDescriptor.
+
+ nested_types: (list of Descriptors) Descriptor references
+ for all protocol message types nested within this one.
+ nested_types_by_name: (dict str -> Descriptor) Same Descriptor
+ objects as in |nested_types|, but indexed by "name" attribute
+ in each Descriptor.
+
+ enum_types: (list of EnumDescriptors) EnumDescriptor references
+ for all enums contained within this type.
+ enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
+ objects as in |enum_types|, but indexed by "name" attribute
+ in each EnumDescriptor.
+ enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
+ from enum value name to EnumValueDescriptor for that value.
+
+ extensions: (list of FieldDescriptor) All extensions defined directly
+ within this message type (NOT within a nested type).
+ extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
+ objects as |extensions|, but indexed by "name" attribute of each
+ FieldDescriptor.
+
+ is_extendable: Does this type define any extension ranges?
+
+ options: (descriptor_pb2.MessageOptions) Protocol message options or None
+ to use default message options.
+
+ file: (FileDescriptor) Reference to file descriptor.
+ """
+
+ def __init__(self, name, full_name, filename, containing_type, fields,
+ nested_types, enum_types, extensions, options=None,
+ is_extendable=True, extension_ranges=None, file=None,
+ serialized_start=None, serialized_end=None):
+ """Arguments to __init__() are as described in the description
+ of Descriptor fields above.
+
+ Note that filename is an obsolete argument, that is not used anymore.
+ Please use file.name to access this as an attribute.
+ """
+ super(Descriptor, self).__init__(
+ options, 'MessageOptions', name, full_name, file,
+ containing_type, serialized_start=serialized_start,
+ serialized_end=serialized_start)
+
+ # We have fields in addition to fields_by_name and fields_by_number,
+ # so that:
+ # 1. Clients can index fields by "order in which they're listed."
+ # 2. Clients can easily iterate over all fields with the terse
+ # syntax: for f in descriptor.fields: ...
+ self.fields = fields
+ for field in self.fields:
+ field.containing_type = self
+ self.fields_by_number = dict((f.number, f) for f in fields)
+ self.fields_by_name = dict((f.name, f) for f in fields)
+
+ self.nested_types = nested_types
+ self.nested_types_by_name = dict((t.name, t) for t in nested_types)
+
+ self.enum_types = enum_types
+ for enum_type in self.enum_types:
+ enum_type.containing_type = self
+ self.enum_types_by_name = dict((t.name, t) for t in enum_types)
+ self.enum_values_by_name = dict(
+ (v.name, v) for t in enum_types for v in t.values)
+
+ self.extensions = extensions
+ for extension in self.extensions:
+ extension.extension_scope = self
+ self.extensions_by_name = dict((f.name, f) for f in extensions)
+ self.is_extendable = is_extendable
+ self.extension_ranges = extension_ranges
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def EnumValueName(self, enum, value):
+ """Returns the string name of an enum value.
+
+ This is just a small helper method to simplify a common operation.
+
+ Args:
+ enum: string name of the Enum.
+ value: int, value of the enum.
+
+ Returns:
+ string name of the enum value.
+
+ Raises:
+ KeyError if either the Enum doesn't exist or the value is not a valid
+ value for the enum.
+ """
+ return self.enum_types_by_name[enum].values_by_number[value].name
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.DescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.DescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(Descriptor, self).CopyToProto(proto)
+
+
+# TODO(robinson): We should have aggressive checking here,
+# for example:
+# * If you specify a repeated field, you should not be allowed
+# to specify a default value.
+# * [Other examples here as needed].
+#
+# TODO(robinson): for this and other *Descriptor classes, we
+# might also want to lock things down aggressively (e.g.,
+# prevent clients from setting the attributes). Having
+# stronger invariants here in general will reduce the number
+# of runtime checks we must do in reflection.py...
+class FieldDescriptor(DescriptorBase):
+
+ """Descriptor for a single field in a .proto file.
+
+ A FieldDescriptor instance has the following attributes:
+
+ name: (str) Name of this field, exactly as it appears in .proto.
+ full_name: (str) Name of this field, including containing scope. This is
+ particularly relevant for extensions.
+ index: (int) Dense, 0-indexed index giving the order that this
+ field textually appears within its message in the .proto file.
+ number: (int) Tag number declared for this field in the .proto file.
+
+ type: (One of the TYPE_* constants below) Declared type.
+ cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
+ represent this field.
+
+ label: (One of the LABEL_* constants below) Tells whether this
+ field is optional, required, or repeated.
+ has_default_value: (bool) True if this field has a default value defined,
+ otherwise false.
+ default_value: (Varies) Default value of this field. Only
+ meaningful for non-repeated scalar fields. Repeated fields
+ should always set this to [], and non-repeated composite
+ fields should always set this to None.
+
+ containing_type: (Descriptor) Descriptor of the protocol message
+ type that contains this field. Set by the Descriptor constructor
+ if we're passed into one.
+ Somewhat confusingly, for extension fields, this is the
+ descriptor of the EXTENDED message, not the descriptor
+ of the message containing this field. (See is_extension and
+ extension_scope below).
+ message_type: (Descriptor) If a composite field, a descriptor
+ of the message type contained in this field. Otherwise, this is None.
+ enum_type: (EnumDescriptor) If this field contains an enum, a
+ descriptor of that enum. Otherwise, this is None.
+
+ is_extension: True iff this describes an extension field.
+ extension_scope: (Descriptor) Only meaningful if is_extension is True.
+ Gives the message that immediately contains this extension field.
+ Will be None iff we're a top-level (file-level) extension field.
+
+ options: (descriptor_pb2.FieldOptions) Protocol message field options or
+ None to use default field options.
+ """
+
+ # Must be consistent with C++ FieldDescriptor::Type enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ TYPE_DOUBLE = 1
+ TYPE_FLOAT = 2
+ TYPE_INT64 = 3
+ TYPE_UINT64 = 4
+ TYPE_INT32 = 5
+ TYPE_FIXED64 = 6
+ TYPE_FIXED32 = 7
+ TYPE_BOOL = 8
+ TYPE_STRING = 9
+ TYPE_GROUP = 10
+ TYPE_MESSAGE = 11
+ TYPE_BYTES = 12
+ TYPE_UINT32 = 13
+ TYPE_ENUM = 14
+ TYPE_SFIXED32 = 15
+ TYPE_SFIXED64 = 16
+ TYPE_SINT32 = 17
+ TYPE_SINT64 = 18
+ MAX_TYPE = 18
+
+ # Must be consistent with C++ FieldDescriptor::CppType enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ CPPTYPE_INT32 = 1
+ CPPTYPE_INT64 = 2
+ CPPTYPE_UINT32 = 3
+ CPPTYPE_UINT64 = 4
+ CPPTYPE_DOUBLE = 5
+ CPPTYPE_FLOAT = 6
+ CPPTYPE_BOOL = 7
+ CPPTYPE_ENUM = 8
+ CPPTYPE_STRING = 9
+ CPPTYPE_MESSAGE = 10
+ MAX_CPPTYPE = 10
+
+ _PYTHON_TO_CPP_PROTO_TYPE_MAP = {
+ TYPE_DOUBLE: CPPTYPE_DOUBLE,
+ TYPE_FLOAT: CPPTYPE_FLOAT,
+ TYPE_ENUM: CPPTYPE_ENUM,
+ TYPE_INT64: CPPTYPE_INT64,
+ TYPE_SINT64: CPPTYPE_INT64,
+ TYPE_SFIXED64: CPPTYPE_INT64,
+ TYPE_UINT64: CPPTYPE_UINT64,
+ TYPE_FIXED64: CPPTYPE_UINT64,
+ TYPE_INT32: CPPTYPE_INT32,
+ TYPE_SFIXED32: CPPTYPE_INT32,
+ TYPE_SINT32: CPPTYPE_INT32,
+ TYPE_UINT32: CPPTYPE_UINT32,
+ TYPE_FIXED32: CPPTYPE_UINT32,
+ TYPE_BYTES: CPPTYPE_STRING,
+ TYPE_STRING: CPPTYPE_STRING,
+ TYPE_BOOL: CPPTYPE_BOOL,
+ TYPE_MESSAGE: CPPTYPE_MESSAGE,
+ TYPE_GROUP: CPPTYPE_MESSAGE
+ }
+
+ # Must be consistent with C++ FieldDescriptor::Label enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ LABEL_OPTIONAL = 1
+ LABEL_REQUIRED = 2
+ LABEL_REPEATED = 3
+ MAX_LABEL = 3
+
+ def __init__(self, name, full_name, index, number, type, cpp_type, label,
+ default_value, message_type, enum_type, containing_type,
+ is_extension, extension_scope, options=None,
+ has_default_value=True):
+ """The arguments are as described in the description of FieldDescriptor
+ attributes above.
+
+ Note that containing_type may be None, and may be set later if necessary
+ (to deal with circular references between message types, for example).
+ Likewise for extension_scope.
+ """
+ super(FieldDescriptor, self).__init__(options, 'FieldOptions')
+ self.name = name
+ self.full_name = full_name
+ self.index = index
+ self.number = number
+ self.type = type
+ self.cpp_type = cpp_type
+ self.label = label
+ self.has_default_value = has_default_value
+ self.default_value = default_value
+ self.containing_type = containing_type
+ self.message_type = message_type
+ self.enum_type = enum_type
+ self.is_extension = is_extension
+ self.extension_scope = extension_scope
+ if api_implementation.Type() == 'cpp':
+ if is_extension:
+ if api_implementation.Version() == 2:
+ self._cdescriptor = _message.GetExtensionDescriptor(full_name)
+ else:
+ self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
+ else:
+ if api_implementation.Version() == 2:
+ self._cdescriptor = _message.GetFieldDescriptor(full_name)
+ else:
+ self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
+ else:
+ self._cdescriptor = None
+
+ @staticmethod
+ def ProtoTypeToCppProtoType(proto_type):
+ """Converts from a Python proto type to a C++ Proto Type.
+
+ The Python ProtocolBuffer classes specify both the 'Python' datatype and the
+ 'C++' datatype - and they're not the same. This helper method should
+ translate from one to another.
+
+ Args:
+ proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)
+ Returns:
+ descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.
+ Raises:
+ TypeTransformationError: when the Python proto type isn't known.
+ """
+ try:
+ return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]
+ except KeyError:
+ raise TypeTransformationError('Unknown proto_type: %s' % proto_type)
+
+
+class EnumDescriptor(_NestedDescriptorBase):
+
+ """Descriptor for an enum defined in a .proto file.
+
+ An EnumDescriptor instance has the following attributes:
+
+ name: (str) Name of the enum type.
+ full_name: (str) Full name of the type, including package name
+ and any enclosing type(s).
+
+ values: (list of EnumValueDescriptors) List of the values
+ in this enum.
+ values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
+ but indexed by the "name" field of each EnumValueDescriptor.
+ values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
+ but indexed by the "number" field of each EnumValueDescriptor.
+ containing_type: (Descriptor) Descriptor of the immediate containing
+ type of this enum, or None if this is an enum defined at the
+ top level in a .proto file. Set by Descriptor's constructor
+ if we're passed into one.
+ file: (FileDescriptor) Reference to file descriptor.
+ options: (descriptor_pb2.EnumOptions) Enum options message or
+ None to use default enum options.
+ """
+
+ def __init__(self, name, full_name, filename, values,
+ containing_type=None, options=None, file=None,
+ serialized_start=None, serialized_end=None):
+ """Arguments are as described in the attribute description above.
+
+ Note that filename is an obsolete argument, that is not used anymore.
+ Please use file.name to access this as an attribute.
+ """
+ super(EnumDescriptor, self).__init__(
+ options, 'EnumOptions', name, full_name, file,
+ containing_type, serialized_start=serialized_start,
+ serialized_end=serialized_start)
+
+ self.values = values
+ for value in self.values:
+ value.type = self
+ self.values_by_name = dict((v.name, v) for v in values)
+ self.values_by_number = dict((v.number, v) for v in values)
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.EnumDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.EnumDescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(EnumDescriptor, self).CopyToProto(proto)
+
+
+class EnumValueDescriptor(DescriptorBase):
+
+ """Descriptor for a single value within an enum.
+
+ name: (str) Name of this value.
+ index: (int) Dense, 0-indexed index giving the order that this
+ value appears textually within its enum in the .proto file.
+ number: (int) Actual number assigned to this enum value.
+ type: (EnumDescriptor) EnumDescriptor to which this value
+ belongs. Set by EnumDescriptor's constructor if we're
+ passed into one.
+ options: (descriptor_pb2.EnumValueOptions) Enum value options message or
+ None to use default enum value options options.
+ """
+
+ def __init__(self, name, index, number, type=None, options=None):
+ """Arguments are as described in the attribute description above."""
+ super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
+ self.name = name
+ self.index = index
+ self.number = number
+ self.type = type
+
+
+class ServiceDescriptor(_NestedDescriptorBase):
+
+ """Descriptor for a service.
+
+ name: (str) Name of the service.
+ full_name: (str) Full name of the service, including package name.
+ index: (int) 0-indexed index giving the order that this services
+ definition appears withing the .proto file.
+ methods: (list of MethodDescriptor) List of methods provided by this
+ service.
+ options: (descriptor_pb2.ServiceOptions) Service options message or
+ None to use default service options.
+ file: (FileDescriptor) Reference to file info.
+ """
+
+ def __init__(self, name, full_name, index, methods, options=None, file=None,
+ serialized_start=None, serialized_end=None):
+ super(ServiceDescriptor, self).__init__(
+ options, 'ServiceOptions', name, full_name, file,
+ None, serialized_start=serialized_start,
+ serialized_end=serialized_end)
+ self.index = index
+ self.methods = methods
+ # Set the containing service for each method in this service.
+ for method in self.methods:
+ method.containing_service = self
+
+ def FindMethodByName(self, name):
+ """Searches for the specified method, and returns its descriptor."""
+ for method in self.methods:
+ if name == method.name:
+ return method
+ return None
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.ServiceDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.ServiceDescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(ServiceDescriptor, self).CopyToProto(proto)
+
+
+class MethodDescriptor(DescriptorBase):
+
+ """Descriptor for a method in a service.
+
+ name: (str) Name of the method within the service.
+ full_name: (str) Full name of method.
+ index: (int) 0-indexed index of the method inside the service.
+ containing_service: (ServiceDescriptor) The service that contains this
+ method.
+ input_type: The descriptor of the message that this method accepts.
+ output_type: The descriptor of the message that this method returns.
+ options: (descriptor_pb2.MethodOptions) Method options message or
+ None to use default method options.
+ """
+
+ def __init__(self, name, full_name, index, containing_service,
+ input_type, output_type, options=None):
+ """The arguments are as described in the description of MethodDescriptor
+ attributes above.
+
+ Note that containing_service may be None, and may be set later if necessary.
+ """
+ super(MethodDescriptor, self).__init__(options, 'MethodOptions')
+ self.name = name
+ self.full_name = full_name
+ self.index = index
+ self.containing_service = containing_service
+ self.input_type = input_type
+ self.output_type = output_type
+
+
+class FileDescriptor(DescriptorBase):
+ """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
+
+ name: name of file, relative to root of source tree.
+ package: name of the package
+ serialized_pb: (str) Byte string of serialized
+ descriptor_pb2.FileDescriptorProto.
+ """
+
+ def __init__(self, name, package, options=None, serialized_pb=None):
+ """Constructor."""
+ super(FileDescriptor, self).__init__(options, 'FileOptions')
+
+ self.message_types_by_name = {}
+ self.name = name
+ self.package = package
+ self.serialized_pb = serialized_pb
+ if (api_implementation.Type() == 'cpp' and
+ self.serialized_pb is not None):
+ if api_implementation.Version() == 2:
+ _message.BuildFile(self.serialized_pb)
+ else:
+ cpp_message.BuildFile(self.serialized_pb)
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.FileDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.FileDescriptorProto.
+ """
+ proto.ParseFromString(self.serialized_pb)
+
+
+def _ParseOptions(message, string):
+ """Parses serialized options.
+
+ This helper function is used to parse serialized options in generated
+ proto2 files. It must not be used outside proto2.
+ """
+ message.ParseFromString(string)
+ return message
+
+
+def MakeDescriptor(desc_proto, package=''):
+ """Make a protobuf Descriptor given a DescriptorProto protobuf.
+
+ Args:
+ desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+ package: Optional package name for the new message Descriptor (string).
+
+ Returns:
+ A Descriptor for protobuf messages.
+ """
+ full_message_name = [desc_proto.name]
+ if package: full_message_name.insert(0, package)
+ fields = []
+ for field_proto in desc_proto.field:
+ full_name = '.'.join(full_message_name + [field_proto.name])
+ field = FieldDescriptor(
+ field_proto.name, full_name, field_proto.number - 1,
+ field_proto.number, field_proto.type,
+ FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
+ field_proto.label, None, None, None, None, False, None,
+ has_default_value=False)
+ fields.append(field)
+
+ desc_name = '.'.join(full_message_name)
+ return Descriptor(desc_proto.name, desc_name, None, None, fields,
+ [], [], [])
diff --git a/code/push/google/protobuf/descriptor_database.py b/code/push/google/protobuf/descriptor_database.py
new file mode 100644
index 0000000..8665d3c
--- /dev/null
+++ b/code/push/google/protobuf/descriptor_database.py
@@ -0,0 +1,120 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides a container for DescriptorProtos."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+
+class DescriptorDatabase(object):
+ """A container accepting FileDescriptorProtos and maps DescriptorProtos."""
+
+ def __init__(self):
+ self._file_desc_protos_by_file = {}
+ self._file_desc_protos_by_symbol = {}
+
+ def Add(self, file_desc_proto):
+ """Adds the FileDescriptorProto and its types to this database.
+
+ Args:
+ file_desc_proto: The FileDescriptorProto to add.
+ """
+
+ self._file_desc_protos_by_file[file_desc_proto.name] = file_desc_proto
+ package = file_desc_proto.package
+ for message in file_desc_proto.message_type:
+ self._file_desc_protos_by_symbol.update(
+ (name, file_desc_proto) for name in _ExtractSymbols(message, package))
+ for enum in file_desc_proto.enum_type:
+ self._file_desc_protos_by_symbol[
+ '.'.join((package, enum.name))] = file_desc_proto
+
+ def FindFileByName(self, name):
+ """Finds the file descriptor proto by file name.
+
+ Typically the file name is a relative path ending to a .proto file. The
+ proto with the given name will have to have been added to this database
+ using the Add method or else an error will be raised.
+
+ Args:
+ name: The file name to find.
+
+ Returns:
+ The file descriptor proto matching the name.
+
+ Raises:
+ KeyError if no file by the given name was added.
+ """
+
+ return self._file_desc_protos_by_file[name]
+
+ def FindFileContainingSymbol(self, symbol):
+ """Finds the file descriptor proto containing the specified symbol.
+
+ The symbol should be a fully qualified name including the file descriptor's
+ package and any containing messages. Some examples:
+
+ 'some.package.name.Message'
+ 'some.package.name.Message.NestedEnum'
+
+ The file descriptor proto containing the specified symbol must be added to
+ this database using the Add method or else an error will be raised.
+
+ Args:
+ symbol: The fully qualified symbol name.
+
+ Returns:
+ The file descriptor proto containing the symbol.
+
+ Raises:
+ KeyError if no file contains the specified symbol.
+ """
+
+ return self._file_desc_protos_by_symbol[symbol]
+
+
+def _ExtractSymbols(desc_proto, package):
+ """Pulls out all the symbols from a descriptor proto.
+
+ Args:
+ desc_proto: The proto to extract symbols from.
+ package: The package containing the descriptor type.
+
+ Yields:
+ The fully qualified name found in the descriptor.
+ """
+
+ message_name = '.'.join((package, desc_proto.name))
+ yield message_name
+ for nested_type in desc_proto.nested_type:
+ for symbol in _ExtractSymbols(nested_type, message_name):
+ yield symbol
+ for enum_type in desc_proto.enum_type:
+ yield '.'.join((message_name, enum_type.name))
diff --git a/code/push/google/protobuf/descriptor_pb2.py b/code/push/google/protobuf/descriptor_pb2.py
new file mode 100644
index 0000000..2b4d54c
--- /dev/null
+++ b/code/push/google/protobuf/descriptor_pb2.py
@@ -0,0 +1,1346 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/descriptor.proto
+
+from push.google.protobuf import descriptor as _descriptor
+from push.google.protobuf import message as _message
+from push.google.protobuf import reflection as _reflection
+# @@protoc_insertion_point(imports)
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='google/protobuf/descriptor.proto',
+ package='google.protobuf',
+ serialized_pb='\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xcb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\"\xa9\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\x94\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"\x8c\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\x7f\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\"\xe9\x03\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12,\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb8\x01\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xbe\x02\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14\x65xperimental_map_key\x18\t \x01(\t\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"x\n\x0b\x45numOptions\x12\x19\n\x0b\x61llow_alias\x18\x02 \x01(\x08:\x04true\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"b\n\x10\x45numValueOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"`\n\x0eServiceOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"_\n\rMethodOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xb1\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x63\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\tB)\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01')
+
+
+
+_FIELDDESCRIPTORPROTO_TYPE = _descriptor.EnumDescriptor(
+ name='Type',
+ full_name='google.protobuf.FieldDescriptorProto.Type',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_DOUBLE', index=0, number=1,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_FLOAT', index=1, number=2,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_INT64', index=2, number=3,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_UINT64', index=3, number=4,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_INT32', index=4, number=5,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_FIXED64', index=5, number=6,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_FIXED32', index=6, number=7,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_BOOL', index=7, number=8,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_STRING', index=8, number=9,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_GROUP', index=9, number=10,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_MESSAGE', index=10, number=11,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_BYTES', index=11, number=12,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_UINT32', index=12, number=13,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_ENUM', index=13, number=14,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_SFIXED32', index=14, number=15,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_SFIXED64', index=15, number=16,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_SINT32', index=16, number=17,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='TYPE_SINT64', index=17, number=18,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=1298,
+ serialized_end=1608,
+)
+
+_FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor(
+ name='Label',
+ full_name='google.protobuf.FieldDescriptorProto.Label',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='LABEL_OPTIONAL', index=0, number=1,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='LABEL_REQUIRED', index=1, number=2,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='LABEL_REPEATED', index=2, number=3,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=1610,
+ serialized_end=1677,
+)
+
+_FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor(
+ name='OptimizeMode',
+ full_name='google.protobuf.FileOptions.OptimizeMode',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='SPEED', index=0, number=1,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='CODE_SIZE', index=1, number=2,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='LITE_RUNTIME', index=2, number=3,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=2629,
+ serialized_end=2687,
+)
+
+_FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor(
+ name='CType',
+ full_name='google.protobuf.FieldOptions.CType',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ _descriptor.EnumValueDescriptor(
+ name='STRING', index=0, number=0,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='CORD', index=1, number=1,
+ options=None,
+ type=None),
+ _descriptor.EnumValueDescriptor(
+ name='STRING_PIECE', index=2, number=2,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=3148,
+ serialized_end=3195,
+)
+
+
+_FILEDESCRIPTORSET = _descriptor.Descriptor(
+ name='FileDescriptorSet',
+ full_name='google.protobuf.FileDescriptorSet',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0,
+ number=1, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=53,
+ serialized_end=124,
+)
+
+
+_FILEDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='FileDescriptorProto',
+ full_name='google.protobuf.FileDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2,
+ number=3, type=9, cpp_type=9, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='public_dependency', full_name='google.protobuf.FileDescriptorProto.public_dependency', index=3,
+ number=10, type=5, cpp_type=1, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='weak_dependency', full_name='google.protobuf.FileDescriptorProto.weak_dependency', index=4,
+ number=11, type=5, cpp_type=1, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=5,
+ number=4, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=6,
+ number=5, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='service', full_name='google.protobuf.FileDescriptorProto.service', index=7,
+ number=6, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=8,
+ number=7, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.FileDescriptorProto.options', index=9,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='source_code_info', full_name='google.protobuf.FileDescriptorProto.source_code_info', index=10,
+ number=9, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=127,
+ serialized_end=586,
+)
+
+
+_DESCRIPTORPROTO_EXTENSIONRANGE = _descriptor.Descriptor(
+ name='ExtensionRange',
+ full_name='google.protobuf.DescriptorProto.ExtensionRange',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1,
+ number=2, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=970,
+ serialized_end=1014,
+)
+
+_DESCRIPTORPROTO = _descriptor.Descriptor(
+ name='DescriptorProto',
+ full_name='google.protobuf.DescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.DescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='field', full_name='google.protobuf.DescriptorProto.field', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2,
+ number=6, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3,
+ number=3, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4,
+ number=4, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5,
+ number=5, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.DescriptorProto.options', index=6,
+ number=7, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=589,
+ serialized_end=1014,
+)
+
+
+_FIELDDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='FieldDescriptorProto',
+ full_name='google.protobuf.FieldDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1,
+ number=3, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2,
+ number=4, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3,
+ number=5, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4,
+ number=6, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6,
+ number=7, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=7,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FIELDDESCRIPTORPROTO_TYPE,
+ _FIELDDESCRIPTORPROTO_LABEL,
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1017,
+ serialized_end=1677,
+)
+
+
+_ENUMDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='EnumDescriptorProto',
+ full_name='google.protobuf.EnumDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1680,
+ serialized_end=1820,
+)
+
+
+_ENUMVALUEDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='EnumValueDescriptorProto',
+ full_name='google.protobuf.EnumValueDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1,
+ number=2, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1822,
+ serialized_end=1930,
+)
+
+
+_SERVICEDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='ServiceDescriptorProto',
+ full_name='google.protobuf.ServiceDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1933,
+ serialized_end=2077,
+)
+
+
+_METHODDESCRIPTORPROTO = _descriptor.Descriptor(
+ name='MethodDescriptorProto',
+ full_name='google.protobuf.MethodDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3,
+ number=4, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=2079,
+ serialized_end=2206,
+)
+
+
+_FILEOPTIONS = _descriptor.Descriptor(
+ name='FileOptions',
+ full_name='google.protobuf.FileOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1,
+ number=8, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2,
+ number=10, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='java_generate_equals_and_hash', full_name='google.protobuf.FileOptions.java_generate_equals_and_hash', index=3,
+ number=20, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=4,
+ number=9, type=14, cpp_type=8, label=1,
+ has_default_value=True, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='go_package', full_name='google.protobuf.FileOptions.go_package', index=5,
+ number=11, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=6,
+ number=16, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=7,
+ number=17, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=8,
+ number=18, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=9,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FILEOPTIONS_OPTIMIZEMODE,
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2209,
+ serialized_end=2698,
+)
+
+
+_MESSAGEOPTIONS = _descriptor.Descriptor(
+ name='MessageOptions',
+ full_name='google.protobuf.MessageOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0,
+ number=1, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1,
+ number=2, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=2,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2701,
+ serialized_end=2885,
+)
+
+
+_FIELDOPTIONS = _descriptor.Descriptor(
+ name='FieldOptions',
+ full_name='google.protobuf.FieldOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0,
+ number=1, type=14, cpp_type=8, label=1,
+ has_default_value=True, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='packed', full_name='google.protobuf.FieldOptions.packed', index=1,
+ number=2, type=8, cpp_type=7, label=1,
+ has_default_value=False, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=2,
+ number=5, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=3,
+ number=3, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='experimental_map_key', full_name='google.protobuf.FieldOptions.experimental_map_key', index=4,
+ number=9, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='weak', full_name='google.protobuf.FieldOptions.weak', index=5,
+ number=10, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=6,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FIELDOPTIONS_CTYPE,
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2888,
+ serialized_end=3206,
+)
+
+
+_ENUMOPTIONS = _descriptor.Descriptor(
+ name='EnumOptions',
+ full_name='google.protobuf.EnumOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0,
+ number=2, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=True,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=1,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3208,
+ serialized_end=3328,
+)
+
+
+_ENUMVALUEOPTIONS = _descriptor.Descriptor(
+ name='EnumValueOptions',
+ full_name='google.protobuf.EnumValueOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3330,
+ serialized_end=3428,
+)
+
+
+_SERVICEOPTIONS = _descriptor.Descriptor(
+ name='ServiceOptions',
+ full_name='google.protobuf.ServiceOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3430,
+ serialized_end=3526,
+)
+
+
+_METHODOPTIONS = _descriptor.Descriptor(
+ name='MethodOptions',
+ full_name='google.protobuf.MethodOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3528,
+ serialized_end=3623,
+)
+
+
+_UNINTERPRETEDOPTION_NAMEPART = _descriptor.Descriptor(
+ name='NamePart',
+ full_name='google.protobuf.UninterpretedOption.NamePart',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0,
+ number=1, type=9, cpp_type=9, label=2,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1,
+ number=2, type=8, cpp_type=7, label=2,
+ has_default_value=False, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3861,
+ serialized_end=3912,
+)
+
+_UNINTERPRETEDOPTION = _descriptor.Descriptor(
+ name='UninterpretedOption',
+ full_name='google.protobuf.UninterpretedOption',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.UninterpretedOption.name', index=0,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2,
+ number=4, type=4, cpp_type=4, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3,
+ number=5, type=3, cpp_type=2, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4,
+ number=6, type=1, cpp_type=5, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5,
+ number=7, type=12, cpp_type=9, label=1,
+ has_default_value=False, default_value="",
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6,
+ number=8, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3626,
+ serialized_end=3912,
+)
+
+
+_SOURCECODEINFO_LOCATION = _descriptor.Descriptor(
+ name='Location',
+ full_name='google.protobuf.SourceCodeInfo.Location',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='path', full_name='google.protobuf.SourceCodeInfo.Location.path', index=0,
+ number=1, type=5, cpp_type=1, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='span', full_name='google.protobuf.SourceCodeInfo.Location.span', index=1,
+ number=2, type=5, cpp_type=1, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3,
+ number=4, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3993,
+ serialized_end=4092,
+)
+
+_SOURCECODEINFO = _descriptor.Descriptor(
+ name='SourceCodeInfo',
+ full_name='google.protobuf.SourceCodeInfo',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='location', full_name='google.protobuf.SourceCodeInfo.location', index=0,
+ number=1, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_SOURCECODEINFO_LOCATION, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3915,
+ serialized_end=4092,
+)
+
+_FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS
+_FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO
+_DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO;
+_DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE
+_DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS
+_FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL
+_FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE
+_FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS
+_FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO;
+_FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO;
+_ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO
+_ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS
+_ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS
+_SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO
+_SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS
+_METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS
+_FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE
+_FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS;
+_MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE
+_FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS;
+_ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION;
+_UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART
+_SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO;
+_SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION
+DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET
+DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['MethodDescriptorProto'] = _METHODDESCRIPTORPROTO
+DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS
+DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS
+DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS
+DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS
+DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS
+DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS
+DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS
+DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION
+DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO
+
+class FileDescriptorSet(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEDESCRIPTORSET
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+
+class FileDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
+
+class DescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+
+ class ExtensionRange(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _DESCRIPTORPROTO_EXTENSIONRANGE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
+ DESCRIPTOR = _DESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
+
+class FieldDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FIELDDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
+
+class EnumDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
+
+class EnumValueDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
+
+class ServiceDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _SERVICEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
+
+class MethodDescriptorProto(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _METHODDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
+
+class FileOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+
+class MessageOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _MESSAGEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+
+class FieldOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FIELDOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+
+class EnumOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+
+class EnumValueOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMVALUEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+
+class ServiceOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _SERVICEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+
+class MethodOptions(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _METHODOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+
+class UninterpretedOption(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+
+ class NamePart(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _UNINTERPRETEDOPTION_NAMEPART
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
+ DESCRIPTOR = _UNINTERPRETEDOPTION
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
+
+class SourceCodeInfo(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+
+ class Location(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _SOURCECODEINFO_LOCATION
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
+ DESCRIPTOR = _SOURCECODEINFO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/code/push/google/protobuf/descriptor_pool.py b/code/push/google/protobuf/descriptor_pool.py
new file mode 100644
index 0000000..8f1f445
--- /dev/null
+++ b/code/push/google/protobuf/descriptor_pool.py
@@ -0,0 +1,527 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides DescriptorPool to use as a container for proto2 descriptors.
+
+The DescriptorPool is used in conjection with a DescriptorDatabase to maintain
+a collection of protocol buffer descriptors for use when dynamically creating
+message types at runtime.
+
+For most applications protocol buffers should be used via modules generated by
+the protocol buffer compiler tool. This should only be used when the type of
+protocol buffers used in an application or library cannot be predetermined.
+
+Below is a straightforward example on how to use this class:
+
+ pool = DescriptorPool()
+ file_descriptor_protos = [ ... ]
+ for file_descriptor_proto in file_descriptor_protos:
+ pool.Add(file_descriptor_proto)
+ my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType')
+
+The message descriptor can be used in conjunction with the message_factory
+module in order to create a protocol buffer class that can be encoded and
+decoded.
+"""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+
+
+class DescriptorPool(object):
+ """A collection of protobufs dynamically constructed by descriptor protos."""
+
+ def __init__(self, descriptor_db=None):
+ """Initializes a Pool of proto buffs.
+
+ The descriptor_db argument to the constructor is provided to allow
+ specialized file descriptor proto lookup code to be triggered on demand. An
+ example would be an implementation which will read and compile a file
+ specified in a call to FindFileByName() and not require the call to Add()
+ at all. Results from this database will be cached internally here as well.
+
+ Args:
+ descriptor_db: A secondary source of file descriptors.
+ """
+
+ self._internal_db = descriptor_database.DescriptorDatabase()
+ self._descriptor_db = descriptor_db
+ self._descriptors = {}
+ self._enum_descriptors = {}
+ self._file_descriptors = {}
+
+ def Add(self, file_desc_proto):
+ """Adds the FileDescriptorProto and its types to this pool.
+
+ Args:
+ file_desc_proto: The FileDescriptorProto to add.
+ """
+
+ self._internal_db.Add(file_desc_proto)
+
+ def FindFileByName(self, file_name):
+ """Gets a FileDescriptor by file name.
+
+ Args:
+ file_name: The path to the file to get a descriptor for.
+
+ Returns:
+ A FileDescriptor for the named file.
+
+ Raises:
+ KeyError: if the file can not be found in the pool.
+ """
+
+ try:
+ file_proto = self._internal_db.FindFileByName(file_name)
+ except KeyError as error:
+ if self._descriptor_db:
+ file_proto = self._descriptor_db.FindFileByName(file_name)
+ else:
+ raise error
+ if not file_proto:
+ raise KeyError('Cannot find a file named %s' % file_name)
+ return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+ def FindFileContainingSymbol(self, symbol):
+ """Gets the FileDescriptor for the file containing the specified symbol.
+
+ Args:
+ symbol: The name of the symbol to search for.
+
+ Returns:
+ A FileDescriptor that contains the specified symbol.
+
+ Raises:
+ KeyError: if the file can not be found in the pool.
+ """
+
+ try:
+ file_proto = self._internal_db.FindFileContainingSymbol(symbol)
+ except KeyError as error:
+ if self._descriptor_db:
+ file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
+ else:
+ raise error
+ if not file_proto:
+ raise KeyError('Cannot find a file containing %s' % symbol)
+ return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+ def FindMessageTypeByName(self, full_name):
+ """Loads the named descriptor from the pool.
+
+ Args:
+ full_name: The full name of the descriptor to load.
+
+ Returns:
+ The descriptor for the named type.
+ """
+
+ full_name = full_name.lstrip('.') # fix inconsistent qualified name formats
+ if full_name not in self._descriptors:
+ self.FindFileContainingSymbol(full_name)
+ return self._descriptors[full_name]
+
+ def FindEnumTypeByName(self, full_name):
+ """Loads the named enum descriptor from the pool.
+
+ Args:
+ full_name: The full name of the enum descriptor to load.
+
+ Returns:
+ The enum descriptor for the named type.
+ """
+
+ full_name = full_name.lstrip('.') # fix inconsistent qualified name formats
+ if full_name not in self._enum_descriptors:
+ self.FindFileContainingSymbol(full_name)
+ return self._enum_descriptors[full_name]
+
+ def _ConvertFileProtoToFileDescriptor(self, file_proto):
+ """Creates a FileDescriptor from a proto or returns a cached copy.
+
+ This method also has the side effect of loading all the symbols found in
+ the file into the appropriate dictionaries in the pool.
+
+ Args:
+ file_proto: The proto to convert.
+
+ Returns:
+ A FileDescriptor matching the passed in proto.
+ """
+
+ if file_proto.name not in self._file_descriptors:
+ file_descriptor = descriptor.FileDescriptor(
+ name=file_proto.name,
+ package=file_proto.package,
+ options=file_proto.options,
+ serialized_pb=file_proto.SerializeToString())
+ scope = {}
+ dependencies = list(self._GetDeps(file_proto))
+
+ for dependency in dependencies:
+ dep_desc = self.FindFileByName(dependency.name)
+ dep_proto = descriptor_pb2.FileDescriptorProto.FromString(
+ dep_desc.serialized_pb)
+ package = '.' + dep_proto.package
+ package_prefix = package + '.'
+
+ def _strip_package(symbol):
+ if symbol.startswith(package_prefix):
+ return symbol[len(package_prefix):]
+ return symbol
+
+ symbols = list(self._ExtractSymbols(dep_proto.message_type, package))
+ scope.update(symbols)
+ scope.update((_strip_package(k), v) for k, v in symbols)
+
+ symbols = list(self._ExtractEnums(dep_proto.enum_type, package))
+ scope.update(symbols)
+ scope.update((_strip_package(k), v) for k, v in symbols)
+
+ for message_type in file_proto.message_type:
+ message_desc = self._ConvertMessageDescriptor(
+ message_type, file_proto.package, file_descriptor, scope)
+ file_descriptor.message_types_by_name[message_desc.name] = message_desc
+ for enum_type in file_proto.enum_type:
+ self._ConvertEnumDescriptor(enum_type, file_proto.package,
+ file_descriptor, None, scope)
+ for desc_proto in self._ExtractMessages(file_proto.message_type):
+ self._SetFieldTypes(desc_proto, scope)
+
+ for desc_proto in file_proto.message_type:
+ desc = scope[desc_proto.name]
+ file_descriptor.message_types_by_name[desc_proto.name] = desc
+ self.Add(file_proto)
+ self._file_descriptors[file_proto.name] = file_descriptor
+
+ return self._file_descriptors[file_proto.name]
+
+ def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None,
+ scope=None):
+ """Adds the proto to the pool in the specified package.
+
+ Args:
+ desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+ package: The package the proto should be located in.
+ file_desc: The file containing this message.
+ scope: Dict mapping short and full symbols to message and enum types.
+
+ Returns:
+ The added descriptor.
+ """
+
+ if package:
+ desc_name = '.'.join((package, desc_proto.name))
+ else:
+ desc_name = desc_proto.name
+
+ if file_desc is None:
+ file_name = None
+ else:
+ file_name = file_desc.name
+
+ if scope is None:
+ scope = {}
+
+ nested = [
+ self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope)
+ for nested in desc_proto.nested_type]
+ enums = [
+ self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
+ for enum in desc_proto.enum_type]
+ fields = [self._MakeFieldDescriptor(field, desc_name, index)
+ for index, field in enumerate(desc_proto.field)]
+ extensions = [self._MakeFieldDescriptor(extension, desc_name, True)
+ for index, extension in enumerate(desc_proto.extension)]
+ extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
+ if extension_ranges:
+ is_extendable = True
+ else:
+ is_extendable = False
+ desc = descriptor.Descriptor(
+ name=desc_proto.name,
+ full_name=desc_name,
+ filename=file_name,
+ containing_type=None,
+ fields=fields,
+ nested_types=nested,
+ enum_types=enums,
+ extensions=extensions,
+ options=desc_proto.options,
+ is_extendable=is_extendable,
+ extension_ranges=extension_ranges,
+ file=file_desc,
+ serialized_start=None,
+ serialized_end=None)
+ for nested in desc.nested_types:
+ nested.containing_type = desc
+ for enum in desc.enum_types:
+ enum.containing_type = desc
+ scope[desc_proto.name] = desc
+ scope['.' + desc_name] = desc
+ self._descriptors[desc_name] = desc
+ return desc
+
+ def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
+ containing_type=None, scope=None):
+ """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
+
+ Args:
+ enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message.
+ package: Optional package name for the new message EnumDescriptor.
+ file_desc: The file containing the enum descriptor.
+ containing_type: The type containing this enum.
+ scope: Scope containing available types.
+
+ Returns:
+ The added descriptor
+ """
+
+ if package:
+ enum_name = '.'.join((package, enum_proto.name))
+ else:
+ enum_name = enum_proto.name
+
+ if file_desc is None:
+ file_name = None
+ else:
+ file_name = file_desc.name
+
+ values = [self._MakeEnumValueDescriptor(value, index)
+ for index, value in enumerate(enum_proto.value)]
+ desc = descriptor.EnumDescriptor(name=enum_proto.name,
+ full_name=enum_name,
+ filename=file_name,
+ file=file_desc,
+ values=values,
+ containing_type=containing_type,
+ options=enum_proto.options)
+ scope[enum_proto.name] = desc
+ scope['.%s' % enum_name] = desc
+ self._enum_descriptors[enum_name] = desc
+ return desc
+
+ def _MakeFieldDescriptor(self, field_proto, message_name, index,
+ is_extension=False):
+ """Creates a field descriptor from a FieldDescriptorProto.
+
+ For message and enum type fields, this method will do a look up
+ in the pool for the appropriate descriptor for that type. If it
+ is unavailable, it will fall back to the _source function to
+ create it. If this type is still unavailable, construction will
+ fail.
+
+ Args:
+ field_proto: The proto describing the field.
+ message_name: The name of the containing message.
+ index: Index of the field
+ is_extension: Indication that this field is for an extension.
+
+ Returns:
+ An initialized FieldDescriptor object
+ """
+
+ if message_name:
+ full_name = '.'.join((message_name, field_proto.name))
+ else:
+ full_name = field_proto.name
+
+ return descriptor.FieldDescriptor(
+ name=field_proto.name,
+ full_name=full_name,
+ index=index,
+ number=field_proto.number,
+ type=field_proto.type,
+ cpp_type=None,
+ message_type=None,
+ enum_type=None,
+ containing_type=None,
+ label=field_proto.label,
+ has_default_value=False,
+ default_value=None,
+ is_extension=is_extension,
+ extension_scope=None,
+ options=field_proto.options)
+
+ def _SetFieldTypes(self, desc_proto, scope):
+ """Sets the field's type, cpp_type, message_type and enum_type.
+
+ Args:
+ desc_proto: The message descriptor to update.
+ scope: Enclosing scope of available types.
+ """
+
+ desc = scope[desc_proto.name]
+ for field_proto, field_desc in zip(desc_proto.field, desc.fields):
+ if field_proto.type_name:
+ type_name = field_proto.type_name
+ if type_name not in scope:
+ type_name = '.' + type_name
+ desc = scope[type_name]
+ else:
+ desc = None
+
+ if not field_proto.HasField('type'):
+ if isinstance(desc, descriptor.Descriptor):
+ field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+ else:
+ field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
+
+ field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
+ field_proto.type)
+
+ if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
+ or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
+ field_desc.message_type = desc
+
+ if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ field_desc.enum_type = desc
+
+ if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ field_desc.has_default = False
+ field_desc.default_value = []
+ elif field_proto.HasField('default_value'):
+ field_desc.has_default = True
+ if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+ field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+ field_desc.default_value = float(field_proto.default_value)
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+ field_desc.default_value = field_proto.default_value
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+ field_desc.default_value = field_proto.default_value.lower() == 'true'
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ field_desc.default_value = field_desc.enum_type.values_by_name[
+ field_proto.default_value].index
+ else:
+ field_desc.default_value = int(field_proto.default_value)
+ else:
+ field_desc.has_default = False
+ field_desc.default_value = None
+
+ field_desc.type = field_proto.type
+
+ for nested_type in desc_proto.nested_type:
+ self._SetFieldTypes(nested_type, scope)
+
+ def _MakeEnumValueDescriptor(self, value_proto, index):
+ """Creates a enum value descriptor object from a enum value proto.
+
+ Args:
+ value_proto: The proto describing the enum value.
+ index: The index of the enum value.
+
+ Returns:
+ An initialized EnumValueDescriptor object.
+ """
+
+ return descriptor.EnumValueDescriptor(
+ name=value_proto.name,
+ index=index,
+ number=value_proto.number,
+ options=value_proto.options,
+ type=None)
+
+ def _ExtractSymbols(self, desc_protos, package):
+ """Pulls out all the symbols from descriptor protos.
+
+ Args:
+ desc_protos: The protos to extract symbols from.
+ package: The package containing the descriptor type.
+ Yields:
+ A two element tuple of the type name and descriptor object.
+ """
+
+ for desc_proto in desc_protos:
+ if package:
+ message_name = '.'.join((package, desc_proto.name))
+ else:
+ message_name = desc_proto.name
+ message_desc = self.FindMessageTypeByName(message_name)
+ yield (message_name, message_desc)
+ for symbol in self._ExtractSymbols(desc_proto.nested_type, message_name):
+ yield symbol
+ for symbol in self._ExtractEnums(desc_proto.enum_type, message_name):
+ yield symbol
+
+ def _ExtractEnums(self, enum_protos, package):
+ """Pulls out all the symbols from enum protos.
+
+ Args:
+ enum_protos: The protos to extract symbols from.
+ package: The package containing the enum type.
+
+ Yields:
+ A two element tuple of the type name and enum descriptor object.
+ """
+
+ for enum_proto in enum_protos:
+ if package:
+ enum_name = '.'.join((package, enum_proto.name))
+ else:
+ enum_name = enum_proto.name
+ enum_desc = self.FindEnumTypeByName(enum_name)
+ yield (enum_name, enum_desc)
+
+ def _ExtractMessages(self, desc_protos):
+ """Pulls out all the message protos from descriptos.
+
+ Args:
+ desc_protos: The protos to extract symbols from.
+
+ Yields:
+ Descriptor protos.
+ """
+
+ for desc_proto in desc_protos:
+ yield desc_proto
+ for message in self._ExtractMessages(desc_proto.nested_type):
+ yield message
+
+ def _GetDeps(self, file_proto):
+ """Recursively finds dependencies for file protos.
+
+ Args:
+ file_proto: The proto to get dependencies from.
+
+ Yields:
+ Each direct and indirect dependency.
+ """
+
+ for dependency in file_proto.dependency:
+ dep_desc = self.FindFileByName(dependency)
+ dep_proto = descriptor_pb2.FileDescriptorProto.FromString(
+ dep_desc.serialized_pb)
+ yield dep_proto
+ for parent_dep in self._GetDeps(dep_proto):
+ yield parent_dep
diff --git a/code/push/google/protobuf/internal/__init__.py b/code/push/google/protobuf/internal/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/code/push/google/protobuf/internal/api_implementation.py b/code/push/google/protobuf/internal/api_implementation.py
new file mode 100644
index 0000000..ce02a32
--- /dev/null
+++ b/code/push/google/protobuf/internal/api_implementation.py
@@ -0,0 +1,87 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+This module is the central entity that determines which implementation of the
+API is used.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import os
+# This environment variable can be used to switch to a certain implementation
+# of the Python API. Right now only 'python' and 'cpp' are valid values. Any
+# other value will be ignored.
+_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
+ 'python')
+
+
+if _implementation_type != 'python':
+ # For now, by default use the pure-Python implementation.
+ # The code below checks if the C extension is available and
+ # uses it if it is available.
+ _implementation_type = 'cpp'
+ ## Determine automatically which implementation to use.
+ #try:
+ # from google.protobuf.internal import cpp_message
+ # _implementation_type = 'cpp'
+ #except ImportError, e:
+ # _implementation_type = 'python'
+
+
+# This environment variable can be used to switch between the two
+# 'cpp' implementations. Right now only 1 and 2 are valid values. Any
+# other value will be ignored.
+_implementation_version_str = os.getenv(
+ 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION',
+ '1')
+
+
+if _implementation_version_str not in ('1', '2'):
+ raise ValueError(
+ "unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: '" +
+ _implementation_version_str + "' (supported versions: 1, 2)"
+ )
+
+
+_implementation_version = int(_implementation_version_str)
+
+
+
+# Usage of this function is discouraged. Clients shouldn't care which
+# implementation of the API is in use. Note that there is no guarantee
+# that differences between APIs will be maintained.
+# Please don't use this function if possible.
+def Type():
+ return _implementation_type
+
+# See comment on 'Type' above.
+def Version():
+ return _implementation_version
diff --git a/code/push/google/protobuf/internal/containers.py b/code/push/google/protobuf/internal/containers.py
new file mode 100644
index 0000000..34b35f8
--- /dev/null
+++ b/code/push/google/protobuf/internal/containers.py
@@ -0,0 +1,269 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains container classes to represent different protocol buffer types.
+
+This file defines container classes which represent categories of protocol
+buffer field types which need extra maintenance. Currently these categories
+are:
+ - Repeated scalar fields - These are all repeated fields which aren't
+ composite (e.g. they are of simple types like int32, string, etc).
+ - Repeated composite fields - Repeated fields which are composite. This
+ includes groups and nested messages.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class BaseContainer(object):
+
+ """Base container class."""
+
+ # Minimizes memory usage and disallows assignment to other attributes.
+ __slots__ = ['_message_listener', '_values']
+
+ def __init__(self, message_listener):
+ """
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedScalarFieldContainer will call this object's
+ Modified() method when it is modified.
+ """
+ self._message_listener = message_listener
+ self._values = []
+
+ def __getitem__(self, key):
+ """Retrieves item by the specified key."""
+ return self._values[key]
+
+ def __len__(self):
+ """Returns the number of elements in the container."""
+ return len(self._values)
+
+ def __ne__(self, other):
+ """Checks if another instance isn't equal to this one."""
+ # The concrete classes should define __eq__.
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __repr__(self):
+ return repr(self._values)
+
+ def sort(self, *args, **kwargs):
+ # Continue to support the old sort_function keyword argument.
+ # This is expected to be a rare occurrence, so use LBYL to avoid
+ # the overhead of actually catching KeyError.
+ if 'sort_function' in kwargs:
+ kwargs['cmp'] = kwargs.pop('sort_function')
+ self._values.sort(*args, **kwargs)
+
+
+class RepeatedScalarFieldContainer(BaseContainer):
+
+ """Simple, type-checked, list-like container for holding repeated scalars."""
+
+ # Disallows assignment to other attributes.
+ __slots__ = ['_type_checker']
+
+ def __init__(self, message_listener, type_checker):
+ """
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedScalarFieldContainer will call this object's
+ Modified() method when it is modified.
+ type_checker: A type_checkers.ValueChecker instance to run on elements
+ inserted into this container.
+ """
+ super(RepeatedScalarFieldContainer, self).__init__(message_listener)
+ self._type_checker = type_checker
+
+ def append(self, value):
+ """Appends an item to the list. Similar to list.append()."""
+ self._type_checker.CheckValue(value)
+ self._values.append(value)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
+ def insert(self, key, value):
+ """Inserts the item at the specified position. Similar to list.insert()."""
+ self._type_checker.CheckValue(value)
+ self._values.insert(key, value)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence. Similar to list.extend()."""
+ if not elem_seq:
+ return
+
+ new_values = []
+ for elem in elem_seq:
+ self._type_checker.CheckValue(elem)
+ new_values.append(elem)
+ self._values.extend(new_values)
+ self._message_listener.Modified()
+
+ def MergeFrom(self, other):
+ """Appends the contents of another repeated field of the same type to this
+ one. We do not check the types of the individual fields.
+ """
+ self._values.extend(other._values)
+ self._message_listener.Modified()
+
+ def remove(self, elem):
+ """Removes an item from the list. Similar to list.remove()."""
+ self._values.remove(elem)
+ self._message_listener.Modified()
+
+ def __setitem__(self, key, value):
+ """Sets the item on the specified position."""
+ self._type_checker.CheckValue(value)
+ self._values[key] = value
+ self._message_listener.Modified()
+
+ def __getslice__(self, start, stop):
+ """Retrieves the subset of items from between the specified indices."""
+ return self._values[start:stop]
+
+ def __setslice__(self, start, stop, values):
+ """Sets the subset of items from between the specified indices."""
+ new_values = []
+ for value in values:
+ self._type_checker.CheckValue(value)
+ new_values.append(value)
+ self._values[start:stop] = new_values
+ self._message_listener.Modified()
+
+ def __delitem__(self, key):
+ """Deletes the item at the specified position."""
+ del self._values[key]
+ self._message_listener.Modified()
+
+ def __delslice__(self, start, stop):
+ """Deletes the subset of items from between the specified indices."""
+ del self._values[start:stop]
+ self._message_listener.Modified()
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ # Special case for the same type which should be common and fast.
+ if isinstance(other, self.__class__):
+ return other._values == self._values
+ # We are presumably comparing against some other sequence type.
+ return other == self._values
+
+
+class RepeatedCompositeFieldContainer(BaseContainer):
+
+ """Simple, list-like container for holding repeated composite fields."""
+
+ # Disallows assignment to other attributes.
+ __slots__ = ['_message_descriptor']
+
+ def __init__(self, message_listener, message_descriptor):
+ """
+ Note that we pass in a descriptor instead of the generated directly,
+ since at the time we construct a _RepeatedCompositeFieldContainer we
+ haven't yet necessarily initialized the type that will be contained in the
+ container.
+
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedCompositeFieldContainer will call this object's
+ Modified() method when it is modified.
+ message_descriptor: A Descriptor instance describing the protocol type
+ that should be present in this container. We'll use the
+ _concrete_class field of this descriptor when the client calls add().
+ """
+ super(RepeatedCompositeFieldContainer, self).__init__(message_listener)
+ self._message_descriptor = message_descriptor
+
+ def add(self, **kwargs):
+ """Adds a new element at the end of the list and returns it. Keyword
+ arguments may be used to initialize the element.
+ """
+ new_element = self._message_descriptor._concrete_class(**kwargs)
+ new_element._SetListener(self._message_listener)
+ self._values.append(new_element)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+ return new_element
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
+ """
+ message_class = self._message_descriptor._concrete_class
+ listener = self._message_listener
+ values = self._values
+ for message in elem_seq:
+ new_element = message_class()
+ new_element._SetListener(listener)
+ new_element.MergeFrom(message)
+ values.append(new_element)
+ listener.Modified()
+
+ def MergeFrom(self, other):
+ """Appends the contents of another repeated field of the same type to this
+ one, copying each individual message.
+ """
+ self.extend(other._values)
+
+ def remove(self, elem):
+ """Removes an item from the list. Similar to list.remove()."""
+ self._values.remove(elem)
+ self._message_listener.Modified()
+
+ def __getslice__(self, start, stop):
+ """Retrieves the subset of items from between the specified indices."""
+ return self._values[start:stop]
+
+ def __delitem__(self, key):
+ """Deletes the item at the specified position."""
+ del self._values[key]
+ self._message_listener.Modified()
+
+ def __delslice__(self, start, stop):
+ """Deletes the subset of items from between the specified indices."""
+ del self._values[start:stop]
+ self._message_listener.Modified()
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ raise TypeError('Can only compare repeated composite fields against '
+ 'other repeated composite fields.')
+ return self._values == other._values
diff --git a/code/push/google/protobuf/internal/cpp_message.py b/code/push/google/protobuf/internal/cpp_message.py
new file mode 100644
index 0000000..23ab9ba
--- /dev/null
+++ b/code/push/google/protobuf/internal/cpp_message.py
@@ -0,0 +1,663 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import copy_reg
+import operator
+from google.protobuf.internal import _net_proto2___python
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import message
+
+
+_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED
+_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL
+_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE
+_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE
+
+
+def GetDescriptorPool():
+ """Creates a new DescriptorPool C++ object."""
+ return _net_proto2___python.NewCDescriptorPool()
+
+
+_pool = GetDescriptorPool()
+
+
+def GetFieldDescriptor(full_field_name):
+ """Searches for a field descriptor given a full field name."""
+ return _pool.FindFieldByName(full_field_name)
+
+
+def BuildFile(content):
+ """Registers a new proto file in the underlying C++ descriptor pool."""
+ _net_proto2___python.BuildFile(content)
+
+
+def GetExtensionDescriptor(full_extension_name):
+ """Searches for extension descriptor given a full field name."""
+ return _pool.FindExtensionByName(full_extension_name)
+
+
+def NewCMessage(full_message_name):
+ """Creates a new C++ protocol message by its name."""
+ return _net_proto2___python.NewCMessage(full_message_name)
+
+
+def ScalarProperty(cdescriptor):
+ """Returns a scalar property for the given descriptor."""
+
+ def Getter(self):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ def Setter(self, value):
+ self._cmsg.SetScalar(cdescriptor, value)
+
+ return property(Getter, Setter)
+
+
+def CompositeProperty(cdescriptor, message_type):
+ """Returns a Python property the given composite field."""
+
+ def Getter(self):
+ sub_message = self._composite_fields.get(cdescriptor.name, None)
+ if sub_message is None:
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ sub_message = message_type._concrete_class(__cmessage=cmessage)
+ self._composite_fields[cdescriptor.name] = sub_message
+ return sub_message
+
+ return property(Getter)
+
+
+class RepeatedScalarContainer(object):
+ """Container for repeated scalar fields."""
+
+ __slots__ = ['_message', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._cfield_descriptor = cfield_descriptor
+
+ def append(self, value):
+ self._cmsg.AddRepeatedScalar(
+ self._cfield_descriptor, value)
+
+ def extend(self, sequence):
+ for element in sequence:
+ self.append(element)
+
+ def insert(self, key, value):
+ values = self[slice(None, None, None)]
+ values.insert(key, value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def remove(self, value):
+ values = self[slice(None, None, None)]
+ values.remove(value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __setitem__(self, key, value):
+ values = self[slice(None, None, None)]
+ values[key] = value
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __getitem__(self, key):
+ return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key)
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key)
+
+ def __len__(self):
+ return len(self[slice(None, None, None)])
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not operator.isSequenceType(other):
+ raise TypeError(
+ 'Can only compare repeated scalar fields against sequences.')
+ # We are presumably comparing against some other sequence type.
+ return other == self[slice(None, None, None)]
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, *args, **kwargs):
+ # Maintain compatibility with the previous interface.
+ if 'sort_function' in kwargs:
+ kwargs['cmp'] = kwargs.pop('sort_function')
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor,
+ sorted(self, *args, **kwargs))
+
+
+def RepeatedScalarProperty(cdescriptor):
+ """Returns a Python property the given repeated scalar field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedScalarContainer(self, cdescriptor)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class RepeatedCompositeContainer(object):
+ """Container for repeated composite fields."""
+
+ __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor, subclass):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._subclass = subclass
+ self._cfield_descriptor = cfield_descriptor
+
+ def add(self, **kwargs):
+ cmessage = self._cmsg.AddMessage(self._cfield_descriptor)
+ return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs)
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
+ """
+ for message in elem_seq:
+ self.add().MergeFrom(message)
+
+ def remove(self, value):
+ # TODO(protocol-devel): This is inefficient as it needs to generate a
+ # message pointer for each message only to do index(). Move this to a C++
+ # extension function.
+ self.__delitem__(self[slice(None, None, None)].index(value))
+
+ def MergeFrom(self, other):
+ for message in other[:]:
+ self.add().MergeFrom(message)
+
+ def __getitem__(self, key):
+ cmessages = self._cmsg.GetRepeatedMessage(
+ self._cfield_descriptor, key)
+ subclass = self._subclass
+ if not isinstance(cmessages, list):
+ return subclass(__cmessage=cmessages, __owner=self._message)
+
+ return [subclass(__cmessage=m, __owner=self._message) for m in cmessages]
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(
+ self._cfield_descriptor, key)
+
+ def __len__(self):
+ return self._cmsg.FieldLength(self._cfield_descriptor)
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ raise TypeError('Can only compare repeated composite fields against '
+ 'other repeated composite fields.')
+ messages = self[slice(None, None, None)]
+ other_messages = other[slice(None, None, None)]
+ return messages == other_messages
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, cmp=None, key=None, reverse=False, **kwargs):
+ # Maintain compatibility with the old interface.
+ if cmp is None and 'sort_function' in kwargs:
+ cmp = kwargs.pop('sort_function')
+
+ # The cmp function, if provided, is passed the results of the key function,
+ # so we only need to wrap one of them.
+ if key is None:
+ index_key = self.__getitem__
+ else:
+ index_key = lambda i: key(self[i])
+
+ # Sort the list of current indexes by the underlying object.
+ indexes = range(len(self))
+ indexes.sort(cmp=cmp, key=index_key, reverse=reverse)
+
+ # Apply the transposition.
+ for dest, src in enumerate(indexes):
+ if dest == src:
+ continue
+ self._cmsg.SwapRepeatedFieldElements(self._cfield_descriptor, dest, src)
+ # Don't swap the same value twice.
+ indexes[src] = src
+
+
+def RepeatedCompositeProperty(cdescriptor, message_type):
+ """Returns a Python property for the given repeated composite field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedCompositeContainer(
+ self, cdescriptor, message_type._concrete_class)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class ExtensionDict(object):
+ """Extension dictionary added to each protocol message."""
+
+ def __init__(self, msg):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._values = {}
+
+ def __setitem__(self, extension, value):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_OPTIONAL or
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ raise TypeError('Extension %r is repeated and/or a composite type.' % (
+ extension.full_name,))
+ self._cmsg.SetScalar(cdescriptor, value)
+ self._values[extension] = value
+
+ def __getitem__(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type != _CPPTYPE_MESSAGE):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ ext = self._values.get(extension, None)
+ if ext is not None:
+ return ext
+
+ ext = self._CreateNewHandle(extension)
+ self._values[extension] = ext
+ return ext
+
+ def ClearExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ self._cmsg.ClearFieldByDescriptor(extension._cdescriptor)
+ if extension in self._values:
+ del self._values[extension]
+
+ def HasExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ return self._cmsg.HasFieldByDescriptor(extension._cdescriptor)
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._message._extensions_by_name.get(name, None)
+
+ def _CreateNewHandle(self, extension):
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ return extension.message_type._concrete_class(__cmessage=cmessage)
+
+ if cdescriptor.label == _LABEL_REPEATED:
+ if cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ return RepeatedCompositeContainer(
+ self._message, cdescriptor, extension.message_type._concrete_class)
+ else:
+ return RepeatedScalarContainer(self._message, cdescriptor)
+ # This shouldn't happen!
+ assert False
+ return None
+
+
+def NewMessage(bases, message_descriptor, dictionary):
+ """Creates a new protocol message *class*."""
+ _AddClassAttributesForNestedExtensions(message_descriptor, dictionary)
+ _AddEnumValues(message_descriptor, dictionary)
+ _AddDescriptors(message_descriptor, dictionary)
+ return bases
+
+
+def InitMessage(message_descriptor, cls):
+ """Constructs a new message instance (called before instance's __init__)."""
+ cls._extensions_by_name = {}
+ _AddInitMethod(message_descriptor, cls)
+ _AddMessageMethods(message_descriptor, cls)
+ _AddPropertiesForExtensions(message_descriptor, cls)
+ copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+def _AddDescriptors(message_descriptor, dictionary):
+ """Sets up a new protocol message class dictionary.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__descriptors'] = {}
+ for field in message_descriptor.fields:
+ dictionary['__descriptors'][field.name] = GetFieldDescriptor(
+ field.full_name)
+
+ dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [
+ '_cmsg', '_owner', '_composite_fields', 'Extensions', '_HACK_REFCOUNTS']
+
+
+def _AddEnumValues(message_descriptor, dictionary):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Args:
+ message_descriptor: Descriptor object for this message type.
+ dictionary: Class dictionary that should be populated.
+ """
+ for enum_type in message_descriptor.enum_types:
+ dictionary[enum_type.name] = enum_type_wrapper.EnumTypeWrapper(enum_type)
+ for enum_value in enum_type.values:
+ dictionary[enum_value.name] = enum_value.number
+
+
+def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary):
+ """Adds class attributes for the nested extensions."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+
+ # Create and attach message field properties to the message class.
+ # This can be done just once per message class, since property setters and
+ # getters are passed the message instance.
+ # This makes message instantiation extremely fast, and at the same time it
+ # doesn't require the creation of property objects for each message instance,
+ # which saves a lot of memory.
+ for field in message_descriptor.fields:
+ field_cdescriptor = cls.__descriptors[field.name]
+ if field.label == _LABEL_REPEATED:
+ if field.cpp_type == _CPPTYPE_MESSAGE:
+ value = RepeatedCompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = RepeatedScalarProperty(field_cdescriptor)
+ elif field.cpp_type == _CPPTYPE_MESSAGE:
+ value = CompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = ScalarProperty(field_cdescriptor)
+ setattr(cls, field.name, value)
+
+ # Attach a constant with the field number.
+ constant_name = field.name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, field.number)
+
+ def Init(self, **kwargs):
+ """Message constructor."""
+ cmessage = kwargs.pop('__cmessage', None)
+ if cmessage:
+ self._cmsg = cmessage
+ else:
+ self._cmsg = NewCMessage(message_descriptor.full_name)
+
+ # Keep a reference to the owner, as the owner keeps a reference to the
+ # underlying protocol buffer message.
+ owner = kwargs.pop('__owner', None)
+ if owner:
+ self._owner = owner
+
+ if message_descriptor.is_extendable:
+ self.Extensions = ExtensionDict(self)
+ else:
+ # Reference counting in the C++ code is broken and depends on
+ # the Extensions reference to keep this object alive during unit
+ # tests (see b/4856052). Remove this once b/4945904 is fixed.
+ self._HACK_REFCOUNTS = self
+ self._composite_fields = {}
+
+ for field_name, field_value in kwargs.iteritems():
+ field_cdescriptor = self.__descriptors.get(field_name, None)
+ if not field_cdescriptor:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+ if field_cdescriptor.label == _LABEL_REPEATED:
+ if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ field_name = getattr(self, field_name)
+ for val in field_value:
+ field_name.add().MergeFrom(val)
+ else:
+ getattr(self, field_name).extend(field_value)
+ elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ getattr(self, field_name).MergeFrom(field_value)
+ else:
+ setattr(self, field_name, field_value)
+
+ Init.__module__ = None
+ Init.__doc__ = None
+ cls.__init__ = Init
+
+
+def _IsMessageSetExtension(field):
+ """Checks if a field is a message set extension."""
+ return (field.is_extension and
+ field.containing_type.has_options and
+ field.containing_type.GetOptions().message_set_wire_format and
+ field.type == _TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == _LABEL_OPTIONAL)
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds the methods to a protocol message class."""
+ if message_descriptor.is_extendable:
+
+ def ClearExtension(self, extension):
+ self.Extensions.ClearExtension(extension)
+
+ def HasExtension(self, extension):
+ return self.Extensions.HasExtension(extension)
+
+ def HasField(self, field_name):
+ return self._cmsg.HasField(field_name)
+
+ def ClearField(self, field_name):
+ child_cmessage = None
+ if field_name in self._composite_fields:
+ child_field = self._composite_fields[field_name]
+ del self._composite_fields[field_name]
+
+ child_cdescriptor = self.__descriptors[field_name]
+ # TODO(anuraag): Support clearing repeated message fields as well.
+ if (child_cdescriptor.label != _LABEL_REPEATED and
+ child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ child_field._owner = None
+ child_cmessage = child_field._cmsg
+
+ if child_cmessage is not None:
+ self._cmsg.ClearField(field_name, child_cmessage)
+ else:
+ self._cmsg.ClearField(field_name)
+
+ def Clear(self):
+ cmessages_to_release = []
+ for field_name, child_field in self._composite_fields.iteritems():
+ child_cdescriptor = self.__descriptors[field_name]
+ # TODO(anuraag): Support clearing repeated message fields as well.
+ if (child_cdescriptor.label != _LABEL_REPEATED and
+ child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ child_field._owner = None
+ cmessages_to_release.append((child_cdescriptor, child_field._cmsg))
+ self._composite_fields.clear()
+ self._cmsg.Clear(cmessages_to_release)
+
+ def IsInitialized(self, errors=None):
+ if self._cmsg.IsInitialized():
+ return True
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors());
+ return False
+
+ def SerializeToString(self):
+ if not self.IsInitialized():
+ raise message.EncodeError(
+ 'Message %s is missing required fields: %s' % (
+ self._cmsg.full_name, ','.join(self.FindInitializationErrors())))
+ return self._cmsg.SerializeToString()
+
+ def SerializePartialToString(self):
+ return self._cmsg.SerializePartialToString()
+
+ def ParseFromString(self, serialized):
+ self.Clear()
+ self.MergeFromString(serialized)
+
+ def MergeFromString(self, serialized):
+ byte_size = self._cmsg.MergeFromString(serialized)
+ if byte_size < 0:
+ raise message.DecodeError('Unable to merge from string.')
+ return byte_size
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s." % (cls.__name__, type(msg).__name__))
+ self._cmsg.MergeFrom(msg._cmsg)
+
+ def CopyFrom(self, msg):
+ self._cmsg.CopyFrom(msg._cmsg)
+
+ def ByteSize(self):
+ return self._cmsg.ByteSize()
+
+ def SetInParent(self):
+ return self._cmsg.SetInParent()
+
+ def ListFields(self):
+ all_fields = []
+ field_list = self._cmsg.ListFields()
+ fields_by_name = cls.DESCRIPTOR.fields_by_name
+ for is_extension, field_name in field_list:
+ if is_extension:
+ extension = cls._extensions_by_name[field_name]
+ all_fields.append((extension, self.Extensions[extension]))
+ else:
+ field_descriptor = fields_by_name[field_name]
+ all_fields.append(
+ (field_descriptor, getattr(self, field_name)))
+ all_fields.sort(key=lambda item: item[0].number)
+ return all_fields
+
+ def FindInitializationErrors(self):
+ return self._cmsg.FindInitializationErrors()
+
+ def __str__(self):
+ return self._cmsg.DebugString()
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ return False
+ return self.ListFields() == other.ListFields()
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __unicode__(self):
+ # Lazy import to prevent circular import when text_format imports this file.
+ from google.protobuf import text_format
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+
+ # Attach the local methods to the message class.
+ for key, value in locals().copy().iteritems():
+ if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
+ setattr(cls, key, value)
+
+ # Static methods:
+
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ if _IsMessageSetExtension(extension_handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(string):
+ msg = cls()
+ msg.MergeFromString(string)
+ return msg
+ cls.FromString = staticmethod(FromString)
+
+
+
+def _AddPropertiesForExtensions(message_descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, extension_field.number)
diff --git a/code/push/google/protobuf/internal/decoder.py b/code/push/google/protobuf/internal/decoder.py
new file mode 100644
index 0000000..9ad5a29
--- /dev/null
+++ b/code/push/google/protobuf/internal/decoder.py
@@ -0,0 +1,720 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Code for decoding protocol buffer primitives.
+
+This code is very similar to encoder.py -- read the docs for that module first.
+
+A "decoder" is a function with the signature:
+ Decode(buffer, pos, end, message, field_dict)
+The arguments are:
+ buffer: The string containing the encoded message.
+ pos: The current position in the string.
+ end: The position in the string where the current message ends. May be
+ less than len(buffer) if we're reading a sub-message.
+ message: The message object into which we're parsing.
+ field_dict: message._fields (avoids a hashtable lookup).
+The decoder reads the field and stores it into field_dict, returning the new
+buffer position. A decoder for a repeated field may proactively decode all of
+the elements of that field, if they appear consecutively.
+
+Note that decoders may throw any of the following:
+ IndexError: Indicates a truncated message.
+ struct.error: Unpacking of a fixed-width field failed.
+ message.DecodeError: Other errors.
+
+Decoders are expected to raise an exception if they are called with pos > end.
+This allows callers to be lax about bounds checking: it's fineto read past
+"end" as long as you are sure that someone else will notice and throw an
+exception later on.
+
+Something up the call stack is expected to catch IndexError and struct.error
+and convert them to message.DecodeError.
+
+Decoders are constructed using decoder constructors with the signature:
+ MakeDecoder(field_number, is_repeated, is_packed, key, new_default)
+The arguments are:
+ field_number: The field number of the field we want to decode.
+ is_repeated: Is the field a repeated field? (bool)
+ is_packed: Is the field a packed field? (bool)
+ key: The key to use when looking up the field within field_dict.
+ (This is actually the FieldDescriptor but nothing in this
+ file should depend on that.)
+ new_default: A function which takes a message object as a parameter and
+ returns a new instance of the default value for this field.
+ (This is called for repeated fields and sub-messages, when an
+ instance does not already exist.)
+
+As with encoders, we define a decoder constructor for every type of field.
+Then, for every field of every message class we construct an actual decoder.
+That decoder goes into a dict indexed by tag, so when we decode a message
+we repeatedly read a tag, look up the corresponding decoder, and invoke it.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+from push.google.protobuf.internal import encoder
+from push.google.protobuf.internal import wire_format
+from push.google.protobuf import message
+
+
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+_NAN = _POS_INF * 0
+
+
+# This is not for optimization, but rather to avoid conflicts with local
+# variables named "message".
+_DecodeError = message.DecodeError
+
+
+def _VarintDecoder(mask):
+ """Return an encoder for a basic varint value (does not include tag).
+
+ Decoded values will be bitwise-anded with the given mask before being
+ returned, e.g. to limit them to 32 bits. The returned decoder does not
+ take the usual "end" parameter -- the caller is expected to do bounds checking
+ after the fact (often the caller can defer such checking until later). The
+ decoder returns a (value, new_pos) pair.
+ """
+
+ local_ord = ord
+ def DecodeVarint(buffer, pos):
+ result = 0
+ shift = 0
+ while 1:
+ b = local_ord(buffer[pos])
+ result |= ((b & 0x7f) << shift)
+ pos += 1
+ if not (b & 0x80):
+ result &= mask
+ return (result, pos)
+ shift += 7
+ if shift >= 64:
+ raise _DecodeError('Too many bytes when decoding varint.')
+ return DecodeVarint
+
+
+def _SignedVarintDecoder(mask):
+ """Like _VarintDecoder() but decodes signed values."""
+
+ local_ord = ord
+ def DecodeVarint(buffer, pos):
+ result = 0
+ shift = 0
+ while 1:
+ b = local_ord(buffer[pos])
+ result |= ((b & 0x7f) << shift)
+ pos += 1
+ if not (b & 0x80):
+ if result > 0x7fffffffffffffff:
+ result -= (1 << 64)
+ result |= ~mask
+ else:
+ result &= mask
+ return (result, pos)
+ shift += 7
+ if shift >= 64:
+ raise _DecodeError('Too many bytes when decoding varint.')
+ return DecodeVarint
+
+
+_DecodeVarint = _VarintDecoder((1 << 64) - 1)
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1)
+
+# Use these versions for values which must be limited to 32 bits.
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1)
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1)
+
+
+def ReadTag(buffer, pos):
+ """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple.
+
+ We return the raw bytes of the tag rather than decoding them. The raw
+ bytes can then be used to look up the proper decoder. This effectively allows
+ us to trade some work that would be done in pure-python (decoding a varint)
+ for work that is done in C (searching for a byte string in a hash table).
+ In a low-level language it would be much cheaper to decode the varint and
+ use that, but not in Python.
+ """
+
+ start = pos
+ while ord(buffer[pos]) & 0x80:
+ pos += 1
+ pos += 1
+ return (buffer[start:pos], pos)
+
+
+# --------------------------------------------------------------------
+
+
+def _SimpleDecoder(wire_type, decode_value):
+ """Return a constructor for a decoder for fields of a particular type.
+
+ Args:
+ wire_type: The field's wire type.
+ decode_value: A function which decodes an individual value, e.g.
+ _DecodeVarint()
+ """
+
+ def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default):
+ if is_packed:
+ local_DecodeVarint = _DecodeVarint
+ def DecodePackedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ (endpoint, pos) = local_DecodeVarint(buffer, pos)
+ endpoint += pos
+ if endpoint > end:
+ raise _DecodeError('Truncated message.')
+ while pos < endpoint:
+ (element, pos) = decode_value(buffer, pos)
+ value.append(element)
+ if pos > endpoint:
+ del value[-1] # Discard corrupt value.
+ raise _DecodeError('Packed element was truncated.')
+ return pos
+ return DecodePackedField
+ elif is_repeated:
+ tag_bytes = encoder.TagBytes(field_number, wire_type)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (element, new_pos) = decode_value(buffer, pos)
+ value.append(element)
+ # Predict that the next tag is another copy of the same repeated
+ # field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+ # Prediction failed. Return.
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (field_dict[key], pos) = decode_value(buffer, pos)
+ if pos > end:
+ del field_dict[key] # Discard corrupt value.
+ raise _DecodeError('Truncated message.')
+ return pos
+ return DecodeField
+
+ return SpecificDecoder
+
+
+def _ModifiedDecoder(wire_type, decode_value, modify_value):
+ """Like SimpleDecoder but additionally invokes modify_value on every value
+ before storing it. Usually modify_value is ZigZagDecode.
+ """
+
+ # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+ # not enough to make a significant difference.
+
+ def InnerDecode(buffer, pos):
+ (result, new_pos) = decode_value(buffer, pos)
+ return (modify_value(result), new_pos)
+ return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _StructPackDecoder(wire_type, format):
+ """Return a constructor for a decoder for a fixed-width field.
+
+ Args:
+ wire_type: The field's wire type.
+ format: The format string to pass to struct.unpack().
+ """
+
+ value_size = struct.calcsize(format)
+ local_unpack = struct.unpack
+
+ # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+ # not enough to make a significant difference.
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+
+ def InnerDecode(buffer, pos):
+ new_pos = pos + value_size
+ result = local_unpack(format, buffer[pos:new_pos])[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _FloatDecoder():
+ """Returns a decoder for a float field.
+
+ This code works around a bug in struct.unpack for non-finite 32-bit
+ floating-point values.
+ """
+
+ local_unpack = struct.unpack
+
+ def InnerDecode(buffer, pos):
+ # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign
+ # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand.
+ new_pos = pos + 4
+ float_bytes = buffer[pos:new_pos]
+
+ # If this value has all its exponent bits set, then it's non-finite.
+ # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
+ # To avoid that, we parse it specially.
+ if ((float_bytes[3] in '\x7F\xFF')
+ and (float_bytes[2] >= '\x80')):
+ # If at least one significand bit is set...
+ if float_bytes[0:3] != '\x00\x00\x80':
+ return (_NAN, new_pos)
+ # If sign bit is set...
+ if float_bytes[3] == '\xFF':
+ return (_NEG_INF, new_pos)
+ return (_POS_INF, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack('= '\xF0')
+ and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')):
+ return (_NAN, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack(' end:
+ raise _DecodeError('Truncated string.')
+ value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8')
+ return new_pos
+ return DecodeField
+
+
+def BytesDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a bytes field."""
+
+ local_DecodeVarint = _DecodeVarint
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_LENGTH_DELIMITED)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ value.append(buffer[pos:new_pos])
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ field_dict[key] = buffer[pos:new_pos]
+ return new_pos
+ return DecodeField
+
+
+def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a group field."""
+
+ end_tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_END_GROUP)
+ end_tag_len = len(end_tag_bytes)
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_START_GROUP)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read sub-message.
+ pos = value.add()._InternalParse(buffer, pos, end)
+ # Read end tag.
+ new_pos = pos+end_tag_len
+ if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+ raise _DecodeError('Missing group end tag.')
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read sub-message.
+ pos = value._InternalParse(buffer, pos, end)
+ # Read end tag.
+ new_pos = pos+end_tag_len
+ if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+ raise _DecodeError('Missing group end tag.')
+ return new_pos
+ return DecodeField
+
+
+def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a message field."""
+
+ local_DecodeVarint = _DecodeVarint
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_LENGTH_DELIMITED)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read length.
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ # Read sub-message.
+ if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
+ # The only reason _InternalParse would return early is if it
+ # encountered an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read length.
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ # Read sub-message.
+ if value._InternalParse(buffer, pos, new_pos) != new_pos:
+ # The only reason _InternalParse would return early is if it encountered
+ # an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+ return new_pos
+ return DecodeField
+
+
+# --------------------------------------------------------------------
+
+MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)
+
+def MessageSetItemDecoder(extensions_by_number):
+ """Returns a decoder for a MessageSet item.
+
+ The parameter is the _extensions_by_number map for the message class.
+
+ The message set message looks like this:
+ message MessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required string message = 3;
+ }
+ }
+ """
+
+ type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
+ message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)
+
+ local_ReadTag = ReadTag
+ local_DecodeVarint = _DecodeVarint
+ local_SkipField = SkipField
+
+ def DecodeItem(buffer, pos, end, message, field_dict):
+ message_set_item_start = pos
+ type_id = -1
+ message_start = -1
+ message_end = -1
+
+ # Technically, type_id and message can appear in any order, so we need
+ # a little loop here.
+ while 1:
+ (tag_bytes, pos) = local_ReadTag(buffer, pos)
+ if tag_bytes == type_id_tag_bytes:
+ (type_id, pos) = local_DecodeVarint(buffer, pos)
+ elif tag_bytes == message_tag_bytes:
+ (size, message_start) = local_DecodeVarint(buffer, pos)
+ pos = message_end = message_start + size
+ elif tag_bytes == item_end_tag_bytes:
+ break
+ else:
+ pos = SkipField(buffer, pos, end, tag_bytes)
+ if pos == -1:
+ raise _DecodeError('Missing group end tag.')
+
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+
+ if type_id == -1:
+ raise _DecodeError('MessageSet item missing type_id.')
+ if message_start == -1:
+ raise _DecodeError('MessageSet item missing message.')
+
+ extension = extensions_by_number.get(type_id)
+ if extension is not None:
+ value = field_dict.get(extension)
+ if value is None:
+ value = field_dict.setdefault(
+ extension, extension.message_type._concrete_class())
+ if value._InternalParse(buffer, message_start,message_end) != message_end:
+ # The only reason _InternalParse would return early is if it encountered
+ # an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+ else:
+ if not message._unknown_fields:
+ message._unknown_fields = []
+ message._unknown_fields.append((MESSAGE_SET_ITEM_TAG,
+ buffer[message_set_item_start:pos]))
+
+ return pos
+
+ return DecodeItem
+
+# --------------------------------------------------------------------
+# Optimization is not as heavy here because calls to SkipField() are rare,
+# except for handling end-group tags.
+
+def _SkipVarint(buffer, pos, end):
+ """Skip a varint value. Returns the new position."""
+
+ while ord(buffer[pos]) & 0x80:
+ pos += 1
+ pos += 1
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipFixed64(buffer, pos, end):
+ """Skip a fixed64 value. Returns the new position."""
+
+ pos += 8
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipLengthDelimited(buffer, pos, end):
+ """Skip a length-delimited value. Returns the new position."""
+
+ (size, pos) = _DecodeVarint(buffer, pos)
+ pos += size
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipGroup(buffer, pos, end):
+ """Skip sub-group. Returns the new position."""
+
+ while 1:
+ (tag_bytes, pos) = ReadTag(buffer, pos)
+ new_pos = SkipField(buffer, pos, end, tag_bytes)
+ if new_pos == -1:
+ return pos
+ pos = new_pos
+
+def _EndGroup(buffer, pos, end):
+ """Skipping an END_GROUP tag returns -1 to tell the parent loop to break."""
+
+ return -1
+
+def _SkipFixed32(buffer, pos, end):
+ """Skip a fixed32 value. Returns the new position."""
+
+ pos += 4
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _RaiseInvalidWireType(buffer, pos, end):
+ """Skip function for unknown wire types. Raises an exception."""
+
+ raise _DecodeError('Tag had invalid wire type.')
+
+def _FieldSkipper():
+ """Constructs the SkipField function."""
+
+ WIRETYPE_TO_SKIPPER = [
+ _SkipVarint,
+ _SkipFixed64,
+ _SkipLengthDelimited,
+ _SkipGroup,
+ _EndGroup,
+ _SkipFixed32,
+ _RaiseInvalidWireType,
+ _RaiseInvalidWireType,
+ ]
+
+ wiretype_mask = wire_format.TAG_TYPE_MASK
+ local_ord = ord
+
+ def SkipField(buffer, pos, end, tag_bytes):
+ """Skips a field with the specified tag.
+
+ |pos| should point to the byte immediately after the tag.
+
+ Returns:
+ The new position (after the tag value), or -1 if the tag is an end-group
+ tag (in which case the calling loop should break).
+ """
+
+ # The wire type is always in the first byte since varints are little-endian.
+ wire_type = local_ord(tag_bytes[0]) & wiretype_mask
+ return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
+
+ return SkipField
+
+SkipField = _FieldSkipper()
diff --git a/code/push/google/protobuf/internal/descriptor_database_test.py b/code/push/google/protobuf/internal/descriptor_database_test.py
new file mode 100644
index 0000000..d0ca789
--- /dev/null
+++ b/code/push/google/protobuf/internal/descriptor_database_test.py
@@ -0,0 +1,63 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.descriptor_database."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import unittest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+
+
+class DescriptorDatabaseTest(unittest.TestCase):
+
+ def testAdd(self):
+ db = descriptor_database.DescriptorDatabase()
+ file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+ db.Add(file_desc_proto)
+
+ self.assertEquals(file_desc_proto, db.FindFileByName(
+ 'net/proto2/python/internal/factory_test2.proto'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory2Message'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory2Message.NestedFactory2Message'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory2Enum'))
+ self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory2Message.NestedFactory2Enum'))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/descriptor_pool_test.py b/code/push/google/protobuf/internal/descriptor_pool_test.py
new file mode 100644
index 0000000..a615d78
--- /dev/null
+++ b/code/push/google/protobuf/internal/descriptor_pool_test.py
@@ -0,0 +1,220 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.descriptor_pool."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import unittest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+
+
+class DescriptorPoolTest(unittest.TestCase):
+
+ def setUp(self):
+ self.pool = descriptor_pool.DescriptorPool()
+ self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test1_pb2.DESCRIPTOR.serialized_pb)
+ self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+ self.pool.Add(self.factory_test1_fd)
+ self.pool.Add(self.factory_test2_fd)
+
+ def testFindFileByName(self):
+ name1 = 'net/proto2/python/internal/factory_test1.proto'
+ file_desc1 = self.pool.FindFileByName(name1)
+ self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+ self.assertEquals(name1, file_desc1.name)
+ self.assertEquals('net.proto2.python.internal', file_desc1.package)
+ self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+ name2 = 'net/proto2/python/internal/factory_test2.proto'
+ file_desc2 = self.pool.FindFileByName(name2)
+ self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+ self.assertEquals(name2, file_desc2.name)
+ self.assertEquals('net.proto2.python.internal', file_desc2.package)
+ self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+ def testFindFileByNameFailure(self):
+ try:
+ self.pool.FindFileByName('Does not exist')
+ self.fail('Expected KeyError')
+ except KeyError:
+ pass
+
+ def testFindFileContainingSymbol(self):
+ file_desc1 = self.pool.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory1Message')
+ self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+ self.assertEquals('net/proto2/python/internal/factory_test1.proto',
+ file_desc1.name)
+ self.assertEquals('net.proto2.python.internal', file_desc1.package)
+ self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+ file_desc2 = self.pool.FindFileContainingSymbol(
+ 'net.proto2.python.internal.Factory2Message')
+ self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+ self.assertEquals('net/proto2/python/internal/factory_test2.proto',
+ file_desc2.name)
+ self.assertEquals('net.proto2.python.internal', file_desc2.package)
+ self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+ def testFindFileContainingSymbolFailure(self):
+ try:
+ self.pool.FindFileContainingSymbol('Does not exist')
+ self.fail('Expected KeyError')
+ except KeyError:
+ pass
+
+ def testFindMessageTypeByName(self):
+ msg1 = self.pool.FindMessageTypeByName(
+ 'net.proto2.python.internal.Factory1Message')
+ self.assertIsInstance(msg1, descriptor.Descriptor)
+ self.assertEquals('Factory1Message', msg1.name)
+ self.assertEquals('net.proto2.python.internal.Factory1Message',
+ msg1.full_name)
+ self.assertEquals(None, msg1.containing_type)
+
+ nested_msg1 = msg1.nested_types[0]
+ self.assertEquals('NestedFactory1Message', nested_msg1.name)
+ self.assertEquals(msg1, nested_msg1.containing_type)
+
+ nested_enum1 = msg1.enum_types[0]
+ self.assertEquals('NestedFactory1Enum', nested_enum1.name)
+ self.assertEquals(msg1, nested_enum1.containing_type)
+
+ self.assertEquals(nested_msg1, msg1.fields_by_name[
+ 'nested_factory_1_message'].message_type)
+ self.assertEquals(nested_enum1, msg1.fields_by_name[
+ 'nested_factory_1_enum'].enum_type)
+
+ msg2 = self.pool.FindMessageTypeByName(
+ 'net.proto2.python.internal.Factory2Message')
+ self.assertIsInstance(msg2, descriptor.Descriptor)
+ self.assertEquals('Factory2Message', msg2.name)
+ self.assertEquals('net.proto2.python.internal.Factory2Message',
+ msg2.full_name)
+ self.assertIsNone(msg2.containing_type)
+
+ nested_msg2 = msg2.nested_types[0]
+ self.assertEquals('NestedFactory2Message', nested_msg2.name)
+ self.assertEquals(msg2, nested_msg2.containing_type)
+
+ nested_enum2 = msg2.enum_types[0]
+ self.assertEquals('NestedFactory2Enum', nested_enum2.name)
+ self.assertEquals(msg2, nested_enum2.containing_type)
+
+ self.assertEquals(nested_msg2, msg2.fields_by_name[
+ 'nested_factory_2_message'].message_type)
+ self.assertEquals(nested_enum2, msg2.fields_by_name[
+ 'nested_factory_2_enum'].enum_type)
+
+ self.assertTrue(msg2.fields_by_name['int_with_default'].has_default)
+ self.assertEquals(
+ 1776, msg2.fields_by_name['int_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['double_with_default'].has_default)
+ self.assertEquals(
+ 9.99, msg2.fields_by_name['double_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['string_with_default'].has_default)
+ self.assertEquals(
+ 'hello world', msg2.fields_by_name['string_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default)
+ self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value)
+
+ self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default)
+ self.assertEquals(
+ 1, msg2.fields_by_name['enum_with_default'].default_value)
+
+ msg3 = self.pool.FindMessageTypeByName(
+ 'net.proto2.python.internal.Factory2Message.NestedFactory2Message')
+ self.assertEquals(nested_msg2, msg3)
+
+ def testFindMessageTypeByNameFailure(self):
+ try:
+ self.pool.FindMessageTypeByName('Does not exist')
+ self.fail('Expected KeyError')
+ except KeyError:
+ pass
+
+ def testFindEnumTypeByName(self):
+ enum1 = self.pool.FindEnumTypeByName(
+ 'net.proto2.python.internal.Factory1Enum')
+ self.assertIsInstance(enum1, descriptor.EnumDescriptor)
+ self.assertEquals(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number)
+ self.assertEquals(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number)
+
+ nested_enum1 = self.pool.FindEnumTypeByName(
+ 'net.proto2.python.internal.Factory1Message.NestedFactory1Enum')
+ self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor)
+ self.assertEquals(
+ 0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number)
+ self.assertEquals(
+ 1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number)
+
+ enum2 = self.pool.FindEnumTypeByName(
+ 'net.proto2.python.internal.Factory2Enum')
+ self.assertIsInstance(enum2, descriptor.EnumDescriptor)
+ self.assertEquals(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number)
+ self.assertEquals(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number)
+
+ nested_enum2 = self.pool.FindEnumTypeByName(
+ 'net.proto2.python.internal.Factory2Message.NestedFactory2Enum')
+ self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor)
+ self.assertEquals(
+ 0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number)
+ self.assertEquals(
+ 1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number)
+
+ def testFindEnumTypeByNameFailure(self):
+ try:
+ self.pool.FindEnumTypeByName('Does not exist')
+ self.fail('Expected KeyError')
+ except KeyError:
+ pass
+
+ def testUserDefinedDB(self):
+ db = descriptor_database.DescriptorDatabase()
+ self.pool = descriptor_pool.DescriptorPool(db)
+ db.Add(self.factory_test1_fd)
+ db.Add(self.factory_test2_fd)
+ self.testFindMessageTypeByName()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/descriptor_test.py b/code/push/google/protobuf/internal/descriptor_test.py
new file mode 100644
index 0000000..c74f882
--- /dev/null
+++ b/code/push/google/protobuf/internal/descriptor_test.py
@@ -0,0 +1,613 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for google.protobuf.internal.descriptor."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import unittest
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import text_format
+
+
+TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
+name: 'TestEmptyMessage'
+"""
+
+
+class DescriptorTest(unittest.TestCase):
+
+ def setUp(self):
+ self.my_file = descriptor.FileDescriptor(
+ name='some/filename/some.proto',
+ package='protobuf_unittest'
+ )
+ self.my_enum = descriptor.EnumDescriptor(
+ name='ForeignEnum',
+ full_name='protobuf_unittest.ForeignEnum',
+ filename=None,
+ file=self.my_file,
+ values=[
+ descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4),
+ descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5),
+ descriptor.EnumValueDescriptor(name='FOREIGN_BAZ', index=2, number=6),
+ ])
+ self.my_message = descriptor.Descriptor(
+ name='NestedMessage',
+ full_name='protobuf_unittest.TestAllTypes.NestedMessage',
+ filename=None,
+ file=self.my_file,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='bb',
+ full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb',
+ index=0, number=1,
+ type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None),
+ ],
+ nested_types=[],
+ enum_types=[
+ self.my_enum,
+ ],
+ extensions=[])
+ self.my_method = descriptor.MethodDescriptor(
+ name='Bar',
+ full_name='protobuf_unittest.TestService.Bar',
+ index=0,
+ containing_service=None,
+ input_type=None,
+ output_type=None)
+ self.my_service = descriptor.ServiceDescriptor(
+ name='TestServiceWithOptions',
+ full_name='protobuf_unittest.TestServiceWithOptions',
+ file=self.my_file,
+ index=0,
+ methods=[
+ self.my_method
+ ])
+
+ def testEnumValueName(self):
+ self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
+ 'FOREIGN_FOO')
+
+ self.assertEqual(
+ self.my_message.enum_types_by_name[
+ 'ForeignEnum'].values_by_number[4].name,
+ self.my_message.EnumValueName('ForeignEnum', 4))
+
+ def testEnumFixups(self):
+ self.assertEqual(self.my_enum, self.my_enum.values[0].type)
+
+ def testContainingTypeFixups(self):
+ self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
+ self.assertEqual(self.my_message, self.my_enum.containing_type)
+
+ def testContainingServiceFixups(self):
+ self.assertEqual(self.my_service, self.my_method.containing_service)
+
+ def testGetOptions(self):
+ self.assertEqual(self.my_enum.GetOptions(),
+ descriptor_pb2.EnumOptions())
+ self.assertEqual(self.my_enum.values[0].GetOptions(),
+ descriptor_pb2.EnumValueOptions())
+ self.assertEqual(self.my_message.GetOptions(),
+ descriptor_pb2.MessageOptions())
+ self.assertEqual(self.my_message.fields[0].GetOptions(),
+ descriptor_pb2.FieldOptions())
+ self.assertEqual(self.my_method.GetOptions(),
+ descriptor_pb2.MethodOptions())
+ self.assertEqual(self.my_service.GetOptions(),
+ descriptor_pb2.ServiceOptions())
+
+ def testSimpleCustomOptions(self):
+ file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+ message_descriptor =\
+ unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
+ field_descriptor = message_descriptor.fields_by_name["field1"]
+ enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"]
+ enum_value_descriptor =\
+ message_descriptor.enum_values_by_name["ANENUM_VAL2"]
+ service_descriptor =\
+ unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
+ method_descriptor = service_descriptor.FindMethodByName("Foo")
+
+ file_options = file_descriptor.GetOptions()
+ file_opt1 = unittest_custom_options_pb2.file_opt1
+ self.assertEqual(9876543210, file_options.Extensions[file_opt1])
+ message_options = message_descriptor.GetOptions()
+ message_opt1 = unittest_custom_options_pb2.message_opt1
+ self.assertEqual(-56, message_options.Extensions[message_opt1])
+ field_options = field_descriptor.GetOptions()
+ field_opt1 = unittest_custom_options_pb2.field_opt1
+ self.assertEqual(8765432109, field_options.Extensions[field_opt1])
+ field_opt2 = unittest_custom_options_pb2.field_opt2
+ self.assertEqual(42, field_options.Extensions[field_opt2])
+ enum_options = enum_descriptor.GetOptions()
+ enum_opt1 = unittest_custom_options_pb2.enum_opt1
+ self.assertEqual(-789, enum_options.Extensions[enum_opt1])
+ enum_value_options = enum_value_descriptor.GetOptions()
+ enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
+ self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
+
+ service_options = service_descriptor.GetOptions()
+ service_opt1 = unittest_custom_options_pb2.service_opt1
+ self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
+ method_options = method_descriptor.GetOptions()
+ method_opt1 = unittest_custom_options_pb2.method_opt1
+ self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
+ method_options.Extensions[method_opt1])
+
+ def testDifferentCustomOptionTypes(self):
+ kint32min = -2**31
+ kint64min = -2**63
+ kint32max = 2**31 - 1
+ kint64max = 2**63 - 1
+ kuint32max = 2**32 - 1
+ kuint64max = 2**64 - 1
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(False, message_options.Extensions[
+ unittest_custom_options_pb2.bool_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.int64_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.uint32_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.uint64_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.sint32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.sint64_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.fixed32_opt])
+ self.assertEqual(0, message_options.Extensions[
+ unittest_custom_options_pb2.fixed64_opt])
+ self.assertEqual(kint32min, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed32_opt])
+ self.assertEqual(kint64min, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed64_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(True, message_options.Extensions[
+ unittest_custom_options_pb2.bool_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.int64_opt])
+ self.assertEqual(kuint32max, message_options.Extensions[
+ unittest_custom_options_pb2.uint32_opt])
+ self.assertEqual(kuint64max, message_options.Extensions[
+ unittest_custom_options_pb2.uint64_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.sint32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.sint64_opt])
+ self.assertEqual(kuint32max, message_options.Extensions[
+ unittest_custom_options_pb2.fixed32_opt])
+ self.assertEqual(kuint64max, message_options.Extensions[
+ unittest_custom_options_pb2.fixed64_opt])
+ self.assertEqual(kint32max, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed32_opt])
+ self.assertEqual(kint64max, message_options.Extensions[
+ unittest_custom_options_pb2.sfixed64_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertEqual(-100, message_options.Extensions[
+ unittest_custom_options_pb2.int32_opt])
+ self.assertAlmostEqual(12.3456789, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+ self.assertEqual("Hello, \"World\"", message_options.Extensions[
+ unittest_custom_options_pb2.string_opt])
+ self.assertEqual("Hello\0World", message_options.Extensions[
+ unittest_custom_options_pb2.bytes_opt])
+ dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
+ self.assertEqual(
+ dummy_enum.TEST_OPTION_ENUM_TYPE2,
+ message_options.Extensions[unittest_custom_options_pb2.enum_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertAlmostEqual(12, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(154, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+
+ message_descriptor =\
+ unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
+ message_options = message_descriptor.GetOptions()
+ self.assertAlmostEqual(-12, message_options.Extensions[
+ unittest_custom_options_pb2.float_opt], 6)
+ self.assertAlmostEqual(-154, message_options.Extensions[
+ unittest_custom_options_pb2.double_opt])
+
+ def testComplexExtensionOptions(self):
+ descriptor =\
+ unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
+ options = descriptor.GetOptions()
+ self.assertEqual(42, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].foo)
+ self.assertEqual(324, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(876, options.Extensions[
+ unittest_custom_options_pb2.complex_opt1].Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(987, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].baz)
+ self.assertEqual(654, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.grault])
+ self.assertEqual(743, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.foo)
+ self.assertEqual(1999, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(2008, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(741, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].foo)
+ self.assertEqual(1998, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].Extensions[
+ unittest_custom_options_pb2.quux])
+ self.assertEqual(2121, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].Extensions[
+ unittest_custom_options_pb2.garply].Extensions[
+ unittest_custom_options_pb2.corge].qux)
+ self.assertEqual(1971, options.Extensions[
+ unittest_custom_options_pb2.ComplexOptionType2
+ .ComplexOptionType4.complex_opt4].waldo)
+ self.assertEqual(321, options.Extensions[
+ unittest_custom_options_pb2.complex_opt2].fred.waldo)
+ self.assertEqual(9, options.Extensions[
+ unittest_custom_options_pb2.complex_opt3].qux)
+ self.assertEqual(22, options.Extensions[
+ unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
+ self.assertEqual(24, options.Extensions[
+ unittest_custom_options_pb2.complexopt6].xyzzy)
+
+ # Check that aggregate options were parsed and saved correctly in
+ # the appropriate descriptors.
+ def testAggregateOptions(self):
+ file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+ message_descriptor =\
+ unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
+ field_descriptor = message_descriptor.fields_by_name["fieldname"]
+ enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
+ enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
+ service_descriptor =\
+ unittest_custom_options_pb2.AggregateService.DESCRIPTOR
+ method_descriptor = service_descriptor.FindMethodByName("Method")
+
+ # Tests for the different types of data embedded in fileopt
+ file_options = file_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.fileopt]
+ self.assertEqual(100, file_options.i)
+ self.assertEqual("FileAnnotation", file_options.s)
+ self.assertEqual("NestedFileAnnotation", file_options.sub.s)
+ self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
+ unittest_custom_options_pb2.fileopt].s)
+ self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
+ unittest_custom_options_pb2.AggregateMessageSetElement
+ .message_set_extension].s)
+
+ # Simple tests for all the other types of annotations
+ self.assertEqual(
+ "MessageAnnotation",
+ message_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.msgopt].s)
+ self.assertEqual(
+ "FieldAnnotation",
+ field_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.fieldopt].s)
+ self.assertEqual(
+ "EnumAnnotation",
+ enum_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.enumopt].s)
+ self.assertEqual(
+ "EnumValueAnnotation",
+ enum_value_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.enumvalopt].s)
+ self.assertEqual(
+ "ServiceAnnotation",
+ service_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.serviceopt].s)
+ self.assertEqual(
+ "MethodAnnotation",
+ method_descriptor.GetOptions().Extensions[
+ unittest_custom_options_pb2.methodopt].s)
+
+ def testNestedOptions(self):
+ nested_message =\
+ unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
+ self.assertEqual(1001, nested_message.GetOptions().Extensions[
+ unittest_custom_options_pb2.message_opt1])
+ nested_field = nested_message.fields_by_name["nested_field"]
+ self.assertEqual(1002, nested_field.GetOptions().Extensions[
+ unittest_custom_options_pb2.field_opt1])
+ outer_message =\
+ unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
+ nested_enum = outer_message.enum_types_by_name["NestedEnum"]
+ self.assertEqual(1003, nested_enum.GetOptions().Extensions[
+ unittest_custom_options_pb2.enum_opt1])
+ nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
+ self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
+ unittest_custom_options_pb2.enum_value_opt1])
+ nested_extension = outer_message.extensions_by_name["nested_extension"]
+ self.assertEqual(1005, nested_extension.GetOptions().Extensions[
+ unittest_custom_options_pb2.field_opt2])
+
+ def testFileDescriptorReferences(self):
+ self.assertEqual(self.my_enum.file, self.my_file)
+ self.assertEqual(self.my_message.file, self.my_file)
+
+ def testFileDescriptor(self):
+ self.assertEqual(self.my_file.name, 'some/filename/some.proto')
+ self.assertEqual(self.my_file.package, 'protobuf_unittest')
+
+
+class DescriptorCopyToProtoTest(unittest.TestCase):
+ """Tests for CopyTo functions of Descriptor."""
+
+ def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
+ expected_proto = expected_class()
+ text_format.Merge(expected_ascii, expected_proto)
+
+ self.assertEqual(
+ actual_proto, expected_proto,
+ 'Not equal,\nActual:\n%s\nExpected:\n%s\n'
+ % (str(actual_proto), str(expected_proto)))
+
+ def _InternalTestCopyToProto(self, desc, expected_proto_class,
+ expected_proto_ascii):
+ actual = expected_proto_class()
+ desc.CopyToProto(actual)
+ self._AssertProtoEqual(
+ actual, expected_proto_class, expected_proto_ascii)
+
+ def testCopyToProto_EmptyMessage(self):
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestEmptyMessage.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
+
+ def testCopyToProto_NestedMessage(self):
+ TEST_NESTED_MESSAGE_ASCII = """
+ name: 'NestedMessage'
+ field: <
+ name: 'bb'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_NESTED_MESSAGE_ASCII)
+
+ def testCopyToProto_ForeignNestedMessage(self):
+ TEST_FOREIGN_NESTED_ASCII = """
+ name: 'TestForeignNested'
+ field: <
+ name: 'foreign_nested'
+ number: 1
+ label: 1 # Optional
+ type: 11 # TYPE_MESSAGE
+ type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestForeignNested.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_FOREIGN_NESTED_ASCII)
+
+ def testCopyToProto_ForeignEnum(self):
+ TEST_FOREIGN_ENUM_ASCII = """
+ name: 'ForeignEnum'
+ value: <
+ name: 'FOREIGN_FOO'
+ number: 4
+ >
+ value: <
+ name: 'FOREIGN_BAR'
+ number: 5
+ >
+ value: <
+ name: 'FOREIGN_BAZ'
+ number: 6
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2._FOREIGNENUM,
+ descriptor_pb2.EnumDescriptorProto,
+ TEST_FOREIGN_ENUM_ASCII)
+
+ def testCopyToProto_Options(self):
+ TEST_DEPRECATED_FIELDS_ASCII = """
+ name: 'TestDeprecatedFields'
+ field: <
+ name: 'deprecated_int32'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ options: <
+ deprecated: true
+ >
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_DEPRECATED_FIELDS_ASCII)
+
+ def testCopyToProto_AllExtensions(self):
+ TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
+ name: 'TestEmptyMessageWithExtensions'
+ extension_range: <
+ start: 1
+ end: 536870912
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
+
+ def testCopyToProto_SeveralExtensions(self):
+ TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
+ name: 'TestMultipleExtensionRanges'
+ extension_range: <
+ start: 42
+ end: 43
+ >
+ extension_range: <
+ start: 4143
+ end: 4244
+ >
+ extension_range: <
+ start: 65536
+ end: 536870912
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
+
+ def testCopyToProto_FileDescriptor(self):
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+ name: 'google/protobuf/unittest_import.proto'
+ package: 'protobuf_unittest_import'
+ dependency: 'google/protobuf/unittest_import_public.proto'
+ message_type: <
+ name: 'ImportMessage'
+ field: <
+ name: 'd'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ >
+ >
+ """ +
+ """enum_type: <
+ name: 'ImportEnum'
+ value: <
+ name: 'IMPORT_FOO'
+ number: 7
+ >
+ value: <
+ name: 'IMPORT_BAR'
+ number: 8
+ >
+ value: <
+ name: 'IMPORT_BAZ'
+ number: 9
+ >
+ >
+ options: <
+ java_package: 'com.google.protobuf.test'
+ optimize_for: 1 # SPEED
+ >
+ public_dependency: 0
+ """)
+
+ self._InternalTestCopyToProto(
+ unittest_import_pb2.DESCRIPTOR,
+ descriptor_pb2.FileDescriptorProto,
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+
+ def testCopyToProto_ServiceDescriptor(self):
+ TEST_SERVICE_ASCII = """
+ name: 'TestService'
+ method: <
+ name: 'Foo'
+ input_type: '.protobuf_unittest.FooRequest'
+ output_type: '.protobuf_unittest.FooResponse'
+ >
+ method: <
+ name: 'Bar'
+ input_type: '.protobuf_unittest.BarRequest'
+ output_type: '.protobuf_unittest.BarResponse'
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestService.DESCRIPTOR,
+ descriptor_pb2.ServiceDescriptorProto,
+ TEST_SERVICE_ASCII)
+
+
+class MakeDescriptorTest(unittest.TestCase):
+ def testMakeDescriptorWithUnsignedIntField(self):
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+ file_descriptor_proto.name = 'Foo'
+ message_type = file_descriptor_proto.message_type.add()
+ message_type.name = file_descriptor_proto.name
+ field = message_type.field.add()
+ field.number = 1
+ field.name = 'uint64_field'
+ field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+ field.type = descriptor.FieldDescriptor.TYPE_UINT64
+ result = descriptor.MakeDescriptor(message_type)
+ self.assertEqual(result.fields[0].cpp_type,
+ descriptor.FieldDescriptor.CPPTYPE_UINT64)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/encoder.py b/code/push/google/protobuf/internal/encoder.py
new file mode 100644
index 0000000..8f624a1
--- /dev/null
+++ b/code/push/google/protobuf/internal/encoder.py
@@ -0,0 +1,769 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Code for encoding protocol message primitives.
+
+Contains the logic for encoding every logical protocol field type
+into one of the 5 physical wire types.
+
+This code is designed to push the Python interpreter's performance to the
+limits.
+
+The basic idea is that at startup time, for every field (i.e. every
+FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
+sizer takes a value of this field's type and computes its byte size. The
+encoder takes a writer function and a value. It encodes the value into byte
+strings and invokes the writer function to write those strings. Typically the
+writer function is the write() method of a cStringIO.
+
+We try to do as much work as possible when constructing the writer and the
+sizer rather than when calling them. In particular:
+* We copy any needed global functions to local variables, so that we do not need
+ to do costly global table lookups at runtime.
+* Similarly, we try to do any attribute lookups at startup time if possible.
+* Every field's tag is encoded to bytes at startup, since it can't change at
+ runtime.
+* Whatever component of the field size we can compute at startup, we do.
+* We *avoid* sharing code if doing so would make the code slower and not sharing
+ does not burden us too much. For example, encoders for repeated fields do
+ not just call the encoders for singular fields in a loop because this would
+ add an extra function call overhead for every loop iteration; instead, we
+ manually inline the single-value encoder into the loop.
+* If a Python function lacks a return statement, Python actually generates
+ instructions to pop the result of the last statement off the stack, push
+ None onto the stack, and then return that. If we really don't care what
+ value is returned, then we can save two instructions by returning the
+ result of the last statement. It looks funny but it helps.
+* We assume that type and bounds checking has happened at a higher level.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+from push.google.protobuf.internal import wire_format
+
+
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+
+
+def _VarintSize(value):
+ """Compute the size of a varint value."""
+ if value <= 0x7f: return 1
+ if value <= 0x3fff: return 2
+ if value <= 0x1fffff: return 3
+ if value <= 0xfffffff: return 4
+ if value <= 0x7ffffffff: return 5
+ if value <= 0x3ffffffffff: return 6
+ if value <= 0x1ffffffffffff: return 7
+ if value <= 0xffffffffffffff: return 8
+ if value <= 0x7fffffffffffffff: return 9
+ return 10
+
+
+def _SignedVarintSize(value):
+ """Compute the size of a signed varint value."""
+ if value < 0: return 10
+ if value <= 0x7f: return 1
+ if value <= 0x3fff: return 2
+ if value <= 0x1fffff: return 3
+ if value <= 0xfffffff: return 4
+ if value <= 0x7ffffffff: return 5
+ if value <= 0x3ffffffffff: return 6
+ if value <= 0x1ffffffffffff: return 7
+ if value <= 0xffffffffffffff: return 8
+ if value <= 0x7fffffffffffffff: return 9
+ return 10
+
+
+def _TagSize(field_number):
+ """Returns the number of bytes required to serialize a tag with this field
+ number."""
+ # Just pass in type 0, since the type won't affect the tag+type size.
+ return _VarintSize(wire_format.PackTag(field_number, 0))
+
+
+# --------------------------------------------------------------------
+# In this section we define some generic sizers. Each of these functions
+# takes parameters specific to a particular field type, e.g. int32 or fixed64.
+# It returns another function which in turn takes parameters specific to a
+# particular field, e.g. the field number and whether it is repeated or packed.
+# Look at the next section to see how these are used.
+
+
+def _SimpleSizer(compute_value_size):
+ """A sizer which uses the function compute_value_size to compute the size of
+ each value. Typically compute_value_size is _VarintSize."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = 0
+ for element in value:
+ result += compute_value_size(element)
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += compute_value_size(element)
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + compute_value_size(value)
+ return FieldSize
+
+ return SpecificSizer
+
+
+def _ModifiedSizer(compute_value_size, modify_value):
+ """Like SimpleSizer, but modify_value is invoked on each value before it is
+ passed to compute_value_size. modify_value is typically ZigZagEncode."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = 0
+ for element in value:
+ result += compute_value_size(modify_value(element))
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += compute_value_size(modify_value(element))
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + compute_value_size(modify_value(value))
+ return FieldSize
+
+ return SpecificSizer
+
+
+def _FixedSizer(value_size):
+ """Like _SimpleSizer except for a fixed-size field. The input is the size
+ of one value."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = len(value) * value_size
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ element_size = value_size + tag_size
+ def RepeatedFieldSize(value):
+ return len(value) * element_size
+ return RepeatedFieldSize
+ else:
+ field_size = value_size + tag_size
+ def FieldSize(value):
+ return field_size
+ return FieldSize
+
+ return SpecificSizer
+
+
+# ====================================================================
+# Here we declare a sizer constructor for each field type. Each "sizer
+# constructor" is a function that takes (field_number, is_repeated, is_packed)
+# as parameters and returns a sizer, which in turn takes a field value as
+# a parameter and returns its encoded size.
+
+
+Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
+
+UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
+
+SInt32Sizer = SInt64Sizer = _ModifiedSizer(
+ _SignedVarintSize, wire_format.ZigZagEncode)
+
+Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4)
+Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
+
+BoolSizer = _FixedSizer(1)
+
+
+def StringSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a string field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = local_len(element.encode('utf-8'))
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = local_len(value.encode('utf-8'))
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+def BytesSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a bytes field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = local_len(element)
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = local_len(value)
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+def GroupSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a group field."""
+
+ tag_size = _TagSize(field_number) * 2
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += element.ByteSize()
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + value.ByteSize()
+ return FieldSize
+
+
+def MessageSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a message field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = element.ByteSize()
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = value.ByteSize()
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+# --------------------------------------------------------------------
+# MessageSet is special.
+
+
+def MessageSetItemSizer(field_number):
+ """Returns a sizer for extensions of MessageSet.
+
+ The message set message looks like this:
+ message MessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required string message = 3;
+ }
+ }
+ """
+ static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) +
+ _TagSize(3))
+ local_VarintSize = _VarintSize
+
+ def FieldSize(value):
+ l = value.ByteSize()
+ return static_size + local_VarintSize(l) + l
+
+ return FieldSize
+
+
+# ====================================================================
+# Encoders!
+
+
+def _VarintEncoder():
+ """Return an encoder for a basic varint value (does not include tag)."""
+
+ local_chr = chr
+ def EncodeVarint(write, value):
+ bits = value & 0x7f
+ value >>= 7
+ while value:
+ write(local_chr(0x80|bits))
+ bits = value & 0x7f
+ value >>= 7
+ return write(local_chr(bits))
+
+ return EncodeVarint
+
+
+def _SignedVarintEncoder():
+ """Return an encoder for a basic signed varint value (does not include
+ tag)."""
+
+ local_chr = chr
+ def EncodeSignedVarint(write, value):
+ if value < 0:
+ value += (1 << 64)
+ bits = value & 0x7f
+ value >>= 7
+ while value:
+ write(local_chr(0x80|bits))
+ bits = value & 0x7f
+ value >>= 7
+ return write(local_chr(bits))
+
+ return EncodeSignedVarint
+
+
+_EncodeVarint = _VarintEncoder()
+_EncodeSignedVarint = _SignedVarintEncoder()
+
+
+def _VarintBytes(value):
+ """Encode the given integer as a varint and return the bytes. This is only
+ called at startup time so it doesn't need to be fast."""
+
+ pieces = []
+ _EncodeVarint(pieces.append, value)
+ return "".join(pieces)
+
+
+def TagBytes(field_number, wire_type):
+ """Encode the given tag and return the bytes. Only called at startup."""
+
+ return _VarintBytes(wire_format.PackTag(field_number, wire_type))
+
+# --------------------------------------------------------------------
+# As with sizers (see above), we have a number of common encoder
+# implementations.
+
+
+def _SimpleEncoder(wire_type, encode_value, compute_value_size):
+ """Return a constructor for an encoder for fields of a particular type.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ encode_value: A function which encodes an individual value, e.g.
+ _EncodeVarint().
+ compute_value_size: A function which computes the size of an individual
+ value, e.g. _VarintSize().
+ """
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ size = 0
+ for element in value:
+ size += compute_value_size(element)
+ local_EncodeVarint(write, size)
+ for element in value:
+ encode_value(write, element)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ encode_value(write, element)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return encode_value(write, value)
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
+ """Like SimpleEncoder but additionally invokes modify_value on every value
+ before passing it to encode_value. Usually modify_value is ZigZagEncode."""
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ size = 0
+ for element in value:
+ size += compute_value_size(modify_value(element))
+ local_EncodeVarint(write, size)
+ for element in value:
+ encode_value(write, modify_value(element))
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ encode_value(write, modify_value(element))
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return encode_value(write, modify_value(value))
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _StructPackEncoder(wire_type, format):
+ """Return a constructor for an encoder for a fixed-width field.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ format: The format string to pass to struct.pack().
+ """
+
+ value_size = struct.calcsize(format)
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ local_struct_pack = struct.pack
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value) * value_size)
+ for element in value:
+ write(local_struct_pack(format, element))
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ write(local_struct_pack(format, element))
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return write(local_struct_pack(format, value))
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _FloatingPointEncoder(wire_type, format):
+ """Return a constructor for an encoder for float fields.
+
+ This is like StructPackEncoder, but catches errors that may be due to
+ passing non-finite floating-point values to struct.pack, and makes a
+ second attempt to encode those values.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ format: The format string to pass to struct.pack().
+ """
+
+ value_size = struct.calcsize(format)
+ if value_size == 4:
+ def EncodeNonFiniteOrRaise(write, value):
+ # Remember that the serialized form uses little-endian byte order.
+ if value == _POS_INF:
+ write('\x00\x00\x80\x7F')
+ elif value == _NEG_INF:
+ write('\x00\x00\x80\xFF')
+ elif value != value: # NaN
+ write('\x00\x00\xC0\x7F')
+ else:
+ raise
+ elif value_size == 8:
+ def EncodeNonFiniteOrRaise(write, value):
+ if value == _POS_INF:
+ write('\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ elif value == _NEG_INF:
+ write('\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ elif value != value: # NaN
+ write('\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ else:
+ raise
+ else:
+ raise ValueError('Can\'t encode floating-point values that are '
+ '%d bytes long (only 4 or 8)' % value_size)
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ local_struct_pack = struct.pack
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value) * value_size)
+ for element in value:
+ # This try/except block is going to be faster than any code that
+ # we could write to check whether element is finite.
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, value))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, value)
+ return EncodeField
+
+ return SpecificEncoder
+
+
+# ====================================================================
+# Here we declare an encoder constructor for each field type. These work
+# very similarly to sizer constructors, described earlier.
+
+
+Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
+
+UInt32Encoder = UInt64Encoder = _SimpleEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
+
+SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
+ wire_format.ZigZagEncode)
+
+# Note that Python conveniently guarantees that when using the '<' prefix on
+# formats, they will also have the same size across all platforms (as opposed
+# to without the prefix, where their sizes depend on the C compiler's basic
+# type sizes).
+Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' 0)
+ self.assertTrue(isinf(message.neg_inf_double))
+ self.assertTrue(message.neg_inf_double < 0)
+ self.assertTrue(isnan(message.nan_double))
+
+ self.assertTrue(isinf(message.inf_float))
+ self.assertTrue(message.inf_float > 0)
+ self.assertTrue(isinf(message.neg_inf_float))
+ self.assertTrue(message.neg_inf_float < 0)
+ self.assertTrue(isnan(message.nan_float))
+ self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
+
+ def testHasDefaultValues(self):
+ desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+
+ expected_has_default_by_name = {
+ 'optional_int32': False,
+ 'repeated_int32': False,
+ 'optional_nested_message': False,
+ 'default_int32': True,
+ }
+
+ has_default_by_name = dict(
+ [(f.name, f.has_default_value)
+ for f in desc.fields
+ if f.name in expected_has_default_by_name])
+ self.assertEqual(expected_has_default_by_name, has_default_by_name)
+
+ def testContainingTypeBehaviorForExtensions(self):
+ self.assertEqual(unittest_pb2.optional_int32_extension.containing_type,
+ unittest_pb2.TestAllExtensions.DESCRIPTOR)
+ self.assertEqual(unittest_pb2.TestRequired.single.containing_type,
+ unittest_pb2.TestAllExtensions.DESCRIPTOR)
+
+ def testExtensionScope(self):
+ self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope,
+ None)
+ self.assertEqual(unittest_pb2.TestRequired.single.extension_scope,
+ unittest_pb2.TestRequired.DESCRIPTOR)
+
+ def testIsExtension(self):
+ self.assertTrue(unittest_pb2.optional_int32_extension.is_extension)
+ self.assertTrue(unittest_pb2.TestRequired.single.is_extension)
+
+ message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR
+ non_extension_descriptor = message_descriptor.fields_by_name['a']
+ self.assertTrue(not non_extension_descriptor.is_extension)
+
+ def testOptions(self):
+ proto = unittest_mset_pb2.TestMessageSet()
+ self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+ def testMessageWithCustomOptions(self):
+ proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
+ enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
+ self.assertTrue(enum_options is not None)
+ # TODO(gps): We really should test for the presense of the enum_opt1
+ # extension and for its value to be set to -789.
+
+ def testNestedTypes(self):
+ self.assertEquals(
+ set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
+ set([
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+ unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR,
+ unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR,
+ ]))
+ self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, [])
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, [])
+
+ def testContainingType(self):
+ self.assertTrue(
+ unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None)
+ self.assertTrue(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+ def testContainingTypeInEnumDescriptor(self):
+ self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None)
+ self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+ def testPackage(self):
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.file.package,
+ 'protobuf_unittest')
+ desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR
+ self.assertEqual(desc.file.package, 'protobuf_unittest')
+ self.assertEqual(
+ unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package,
+ 'protobuf_unittest_import')
+
+ self.assertEqual(
+ unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest')
+ self.assertEqual(
+ unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package,
+ 'protobuf_unittest')
+ self.assertEqual(
+ unittest_import_pb2._IMPORTENUM.file.package,
+ 'protobuf_unittest_import')
+
+ def testExtensionRange(self):
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, [])
+ self.assertEqual(
+ unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
+ [(1, MAX_EXTENSION)])
+ self.assertEqual(
+ unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
+ [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)])
+
+ def testFileDescriptor(self):
+ self.assertEqual(unittest_pb2.DESCRIPTOR.name,
+ 'google/protobuf/unittest.proto')
+ self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
+ self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
+
+ def testNoGenericServices(self):
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))
+
+ # Make sure unittest_no_generic_services_pb2 has no services subclassing
+ # Proto2 Service class.
+ if hasattr(unittest_no_generic_services_pb2, "TestService"):
+ self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
+ service.Service))
+
+ def testMessageTypesByName(self):
+ file_type = unittest_pb2.DESCRIPTOR
+ self.assertEqual(
+ unittest_pb2._TESTALLTYPES,
+ file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])
+
+ # Nested messages shouldn't be included in the message_types_by_name
+ # dictionary (like in the C++ API).
+ self.assertFalse(
+ unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
+ file_type.message_types_by_name)
+
+ def testPublicImports(self):
+ # Test public imports as embedded message.
+ all_type_proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, all_type_proto.optional_public_import_message.e)
+
+ # PublicImportMessage is actually defined in unittest_import_public_pb2
+ # module, and is public imported by unittest_import_pb2 module.
+ public_import_proto = unittest_import_pb2.PublicImportMessage()
+ self.assertEqual(0, public_import_proto.e)
+ self.assertTrue(unittest_import_public_pb2.PublicImportMessage is
+ unittest_import_pb2.PublicImportMessage)
+
+ def testBadIdentifiers(self):
+ # We're just testing that the code was imported without problems.
+ message = test_bad_identifiers_pb2.TestBadIdentifiers()
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message],
+ "foo")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor],
+ "bar")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection],
+ "baz")
+ self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
+ "qux")
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/message_cpp_test.py b/code/push/google/protobuf/internal/message_cpp_test.py
new file mode 100644
index 0000000..0d84b32
--- /dev/null
+++ b/code/push/google/protobuf/internal/message_cpp_test.py
@@ -0,0 +1,45 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.internal.message_cpp."""
+
+__author__ = 'shahms@google.com (Shahms King)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+
+import unittest
+from google.protobuf.internal.message_test import *
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/message_factory_test.py b/code/push/google/protobuf/internal/message_factory_test.py
new file mode 100644
index 0000000..0bc9be9
--- /dev/null
+++ b/code/push/google/protobuf/internal/message_factory_test.py
@@ -0,0 +1,113 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.message_factory."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import unittest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+
+
+class MessageFactoryTest(unittest.TestCase):
+
+ def setUp(self):
+ self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test1_pb2.DESCRIPTOR.serialized_pb)
+ self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+ factory_test2_pb2.DESCRIPTOR.serialized_pb)
+
+ def _ExerciseDynamicClass(self, cls):
+ msg = cls()
+ msg.mandatory = 42
+ msg.nested_factory_2_enum = 0
+ msg.nested_factory_2_message.value = 'nested message value'
+ msg.factory_1_message.factory_1_enum = 1
+ msg.factory_1_message.nested_factory_1_enum = 0
+ msg.factory_1_message.nested_factory_1_message.value = (
+ 'nested message value')
+ msg.factory_1_message.scalar_value = 22
+ msg.factory_1_message.list_value.extend(['one', 'two', 'three'])
+ msg.factory_1_message.list_value.append('four')
+ msg.factory_1_enum = 1
+ msg.nested_factory_1_enum = 0
+ msg.nested_factory_1_message.value = 'nested message value'
+ msg.circular_message.mandatory = 1
+ msg.circular_message.circular_message.mandatory = 2
+ msg.circular_message.scalar_value = 'one deep'
+ msg.scalar_value = 'zero deep'
+ msg.list_value.extend(['four', 'three', 'two'])
+ msg.list_value.append('one')
+ msg.grouped.add()
+ msg.grouped[0].part_1 = 'hello'
+ msg.grouped[0].part_2 = 'world'
+ msg.grouped.add(part_1='testing', part_2='123')
+ msg.loop.loop.mandatory = 2
+ msg.loop.loop.loop.loop.mandatory = 4
+ serialized = msg.SerializeToString()
+ converted = factory_test2_pb2.Factory2Message.FromString(serialized)
+ reserialized = converted.SerializeToString()
+ self.assertEquals(serialized, reserialized)
+ result = cls.FromString(reserialized)
+ self.assertEquals(msg, result)
+
+ def testGetPrototype(self):
+ db = descriptor_database.DescriptorDatabase()
+ pool = descriptor_pool.DescriptorPool(db)
+ db.Add(self.factory_test1_fd)
+ db.Add(self.factory_test2_fd)
+ factory = message_factory.MessageFactory()
+ cls = factory.GetPrototype(pool.FindMessageTypeByName(
+ 'net.proto2.python.internal.Factory2Message'))
+ self.assertIsNot(cls, factory_test2_pb2.Factory2Message)
+ self._ExerciseDynamicClass(cls)
+ cls2 = factory.GetPrototype(pool.FindMessageTypeByName(
+ 'net.proto2.python.internal.Factory2Message'))
+ self.assertIs(cls, cls2)
+
+ def testGetMessages(self):
+ messages = message_factory.GetMessages([self.factory_test2_fd,
+ self.factory_test1_fd])
+ self.assertContainsSubset(
+ ['net.proto2.python.internal.Factory2Message',
+ 'net.proto2.python.internal.Factory1Message'],
+ messages.keys())
+ self._ExerciseDynamicClass(
+ messages['net.proto2.python.internal.Factory2Message'])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/message_listener.py b/code/push/google/protobuf/internal/message_listener.py
new file mode 100644
index 0000000..1080234
--- /dev/null
+++ b/code/push/google/protobuf/internal/message_listener.py
@@ -0,0 +1,78 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Defines a listener interface for observing certain
+state transitions on Message objects.
+
+Also defines a null implementation of this interface.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class MessageListener(object):
+
+ """Listens for modifications made to a message. Meant to be registered via
+ Message._SetListener().
+
+ Attributes:
+ dirty: If True, then calling Modified() would be a no-op. This can be
+ used to avoid these calls entirely in the common case.
+ """
+
+ def Modified(self):
+ """Called every time the message is modified in such a way that the parent
+ message may need to be updated. This currently means either:
+ (a) The message was modified for the first time, so the parent message
+ should henceforth mark the message as present.
+ (b) The message's cached byte size became dirty -- i.e. the message was
+ modified for the first time after a previous call to ByteSize().
+ Therefore the parent should also mark its byte size as dirty.
+ Note that (a) implies (b), since new objects start out with a client cached
+ size (zero). However, we document (a) explicitly because it is important.
+
+ Modified() will *only* be called in response to one of these two events --
+ not every time the sub-message is modified.
+
+ Note that if the listener's |dirty| attribute is true, then calling
+ Modified at the moment would be a no-op, so it can be skipped. Performance-
+ sensitive callers should check this attribute directly before calling since
+ it will be true most of the time.
+ """
+
+ raise NotImplementedError
+
+
+class NullMessageListener(object):
+
+ """No-op MessageListener implementation."""
+
+ def Modified(self):
+ pass
diff --git a/code/push/google/protobuf/internal/message_test.py b/code/push/google/protobuf/internal/message_test.py
new file mode 100644
index 0000000..53e9d50
--- /dev/null
+++ b/code/push/google/protobuf/internal/message_test.py
@@ -0,0 +1,494 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests python protocol buffers against the golden message.
+
+Note that the golden messages exercise every known field type, thus this
+test ends up exercising and verifying nearly all of the parsing and
+serialization code in the whole library.
+
+TODO(kenton): Merge with wire_format_test? It doesn't make a whole lot of
+sense to call this a test of the "message" module, which only declares an
+abstract interface.
+"""
+
+__author__ = 'gps@google.com (Gregory P. Smith)'
+
+import copy
+import math
+import operator
+import pickle
+
+import unittest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import test_util
+from google.protobuf import message
+
+# Python pre-2.6 does not have isinf() or isnan() functions, so we have
+# to provide our own.
+def isnan(val):
+ # NaN is never equal to itself.
+ return val != val
+def isinf(val):
+ # Infinity times zero equals NaN.
+ return not isnan(val) and isnan(val * 0)
+def IsPosInf(val):
+ return isinf(val) and (val > 0)
+def IsNegInf(val):
+ return isinf(val) and (val < 0)
+
+class MessageTest(unittest.TestCase):
+
+ def testGoldenMessage(self):
+ golden_data = test_util.GoldenFile('golden_message').read()
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ test_util.ExpectAllFieldsSet(self, golden_message)
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+ def testGoldenExtensions(self):
+ golden_data = test_util.GoldenFile('golden_message').read()
+ golden_message = unittest_pb2.TestAllExtensions()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+ def testGoldenPackedMessage(self):
+ golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertEqual(golden_data, all_set.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+ def testGoldenPackedExtensions(self):
+ golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_message = unittest_pb2.TestPackedExtensions()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestPackedExtensions()
+ test_util.SetAllPackedExtensions(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertEqual(golden_data, all_set.SerializeToString())
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+ def testPickleSupport(self):
+ golden_data = test_util.GoldenFile('golden_message').read()
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ pickled_message = pickle.dumps(golden_message)
+
+ unpickled_message = pickle.loads(pickled_message)
+ self.assertEquals(unpickled_message, golden_message)
+
+ def testPickleIncompleteProto(self):
+ golden_message = unittest_pb2.TestRequired(a=1)
+ pickled_message = pickle.dumps(golden_message)
+
+ unpickled_message = pickle.loads(pickled_message)
+ self.assertEquals(unpickled_message, golden_message)
+ self.assertEquals(unpickled_message.a, 1)
+ # This is still an incomplete proto - so serializing should fail
+ self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
+
+ def testPositiveInfinity(self):
+ golden_data = ('\x5D\x00\x00\x80\x7F'
+ '\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+ '\xCD\x02\x00\x00\x80\x7F'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.optional_float))
+ self.assertTrue(IsPosInf(golden_message.optional_double))
+ self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNegativeInfinity(self):
+ golden_data = ('\x5D\x00\x00\x80\xFF'
+ '\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+ '\xCD\x02\x00\x00\x80\xFF'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.optional_float))
+ self.assertTrue(IsNegInf(golden_message.optional_double))
+ self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNotANumber(self):
+ golden_data = ('\x5D\x00\x00\xC0\x7F'
+ '\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
+ '\xCD\x02\x00\x00\xC0\x7F'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.optional_float))
+ self.assertTrue(isnan(golden_message.optional_double))
+ self.assertTrue(isnan(golden_message.repeated_float[0]))
+ self.assertTrue(isnan(golden_message.repeated_double[0]))
+
+ # The protocol buffer may serialize to any one of multiple different
+ # representations of a NaN. Rather than verify a specific representation,
+ # verify the serialized string can be converted into a correctly
+ # behaving protocol buffer.
+ serialized = golden_message.SerializeToString()
+ message = unittest_pb2.TestAllTypes()
+ message.ParseFromString(serialized)
+ self.assertTrue(isnan(message.optional_float))
+ self.assertTrue(isnan(message.optional_double))
+ self.assertTrue(isnan(message.repeated_float[0]))
+ self.assertTrue(isnan(message.repeated_double[0]))
+
+ def testPositiveInfinityPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\x80\x7F'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.packed_float[0]))
+ self.assertTrue(IsPosInf(golden_message.packed_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNegativeInfinityPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\x80\xFF'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.packed_float[0]))
+ self.assertTrue(IsNegInf(golden_message.packed_double[0]))
+ self.assertEqual(golden_data, golden_message.SerializeToString())
+
+ def testNotANumberPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\xC0\x7F'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.packed_float[0]))
+ self.assertTrue(isnan(golden_message.packed_double[0]))
+
+ serialized = golden_message.SerializeToString()
+ message = unittest_pb2.TestPackedTypes()
+ message.ParseFromString(serialized)
+ self.assertTrue(isnan(message.packed_float[0]))
+ self.assertTrue(isnan(message.packed_double[0]))
+
+ def testExtremeFloatValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 127)
+ message.optional_float = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
+ message.optional_float = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_float = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits)
+
+ message.optional_float = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -127)
+ message.optional_float = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127)
+ message.optional_float = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_float = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
+
+ message.optional_float = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
+
+ def testExtremeDoubleValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 1023)
+ message.optional_double = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
+ message.optional_double = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_double = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits)
+
+ message.optional_double = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -1023)
+ message.optional_double = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023)
+ message.optional_double = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_double = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
+
+ message.optional_double = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
+
+ def testSortingRepeatedScalarFieldsDefaultComparator(self):
+ """Check some different types with the default comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ # TODO(mattp): would testing more scalar types strengthen test?
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(3)
+ message.repeated_int32.append(2)
+ message.repeated_int32.sort()
+ self.assertEqual(message.repeated_int32[0], 1)
+ self.assertEqual(message.repeated_int32[1], 2)
+ self.assertEqual(message.repeated_int32[2], 3)
+
+ message.repeated_float.append(1.1)
+ message.repeated_float.append(1.3)
+ message.repeated_float.append(1.2)
+ message.repeated_float.sort()
+ self.assertAlmostEqual(message.repeated_float[0], 1.1)
+ self.assertAlmostEqual(message.repeated_float[1], 1.2)
+ self.assertAlmostEqual(message.repeated_float[2], 1.3)
+
+ message.repeated_string.append('a')
+ message.repeated_string.append('c')
+ message.repeated_string.append('b')
+ message.repeated_string.sort()
+ self.assertEqual(message.repeated_string[0], 'a')
+ self.assertEqual(message.repeated_string[1], 'b')
+ self.assertEqual(message.repeated_string[2], 'c')
+
+ message.repeated_bytes.append('a')
+ message.repeated_bytes.append('c')
+ message.repeated_bytes.append('b')
+ message.repeated_bytes.sort()
+ self.assertEqual(message.repeated_bytes[0], 'a')
+ self.assertEqual(message.repeated_bytes[1], 'b')
+ self.assertEqual(message.repeated_bytes[2], 'c')
+
+ def testSortingRepeatedScalarFieldsCustomComparator(self):
+ """Check some different types with custom comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_int32.append(-3)
+ message.repeated_int32.append(-2)
+ message.repeated_int32.append(-1)
+ message.repeated_int32.sort(lambda x,y: cmp(abs(x), abs(y)))
+ self.assertEqual(message.repeated_int32[0], -1)
+ self.assertEqual(message.repeated_int32[1], -2)
+ self.assertEqual(message.repeated_int32[2], -3)
+
+ message.repeated_string.append('aaa')
+ message.repeated_string.append('bb')
+ message.repeated_string.append('c')
+ message.repeated_string.sort(lambda x,y: cmp(len(x), len(y)))
+ self.assertEqual(message.repeated_string[0], 'c')
+ self.assertEqual(message.repeated_string[1], 'bb')
+ self.assertEqual(message.repeated_string[2], 'aaa')
+
+ def testSortingRepeatedCompositeFieldsCustomComparator(self):
+ """Check passing a custom comparator to sort a repeated composite field."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_nested_message.add().bb = 1
+ message.repeated_nested_message.add().bb = 3
+ message.repeated_nested_message.add().bb = 2
+ message.repeated_nested_message.add().bb = 6
+ message.repeated_nested_message.add().bb = 5
+ message.repeated_nested_message.add().bb = 4
+ message.repeated_nested_message.sort(lambda x,y: cmp(x.bb, y.bb))
+ self.assertEqual(message.repeated_nested_message[0].bb, 1)
+ self.assertEqual(message.repeated_nested_message[1].bb, 2)
+ self.assertEqual(message.repeated_nested_message[2].bb, 3)
+ self.assertEqual(message.repeated_nested_message[3].bb, 4)
+ self.assertEqual(message.repeated_nested_message[4].bb, 5)
+ self.assertEqual(message.repeated_nested_message[5].bb, 6)
+
+ def testRepeatedCompositeFieldSortArguments(self):
+ """Check sorting a repeated composite field using list.sort() arguments."""
+ message = unittest_pb2.TestAllTypes()
+
+ get_bb = operator.attrgetter('bb')
+ cmp_bb = lambda a, b: cmp(a.bb, b.bb)
+ message.repeated_nested_message.add().bb = 1
+ message.repeated_nested_message.add().bb = 3
+ message.repeated_nested_message.add().bb = 2
+ message.repeated_nested_message.add().bb = 6
+ message.repeated_nested_message.add().bb = 5
+ message.repeated_nested_message.add().bb = 4
+ message.repeated_nested_message.sort(key=get_bb)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [1, 2, 3, 4, 5, 6])
+ message.repeated_nested_message.sort(key=get_bb, reverse=True)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [6, 5, 4, 3, 2, 1])
+ message.repeated_nested_message.sort(sort_function=cmp_bb)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [1, 2, 3, 4, 5, 6])
+ message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True)
+ self.assertEqual([k.bb for k in message.repeated_nested_message],
+ [6, 5, 4, 3, 2, 1])
+
+ def testRepeatedScalarFieldSortArguments(self):
+ """Check sorting a scalar field using list.sort() arguments."""
+ message = unittest_pb2.TestAllTypes()
+
+ abs_cmp = lambda a, b: cmp(abs(a), abs(b))
+ message.repeated_int32.append(-3)
+ message.repeated_int32.append(-2)
+ message.repeated_int32.append(-1)
+ message.repeated_int32.sort(key=abs)
+ self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+ message.repeated_int32.sort(key=abs, reverse=True)
+ self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+ message.repeated_int32.sort(sort_function=abs_cmp)
+ self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+ message.repeated_int32.sort(cmp=abs_cmp, reverse=True)
+ self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+
+ len_cmp = lambda a, b: cmp(len(a), len(b))
+ message.repeated_string.append('aaa')
+ message.repeated_string.append('bb')
+ message.repeated_string.append('c')
+ message.repeated_string.sort(key=len)
+ self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+ message.repeated_string.sort(key=len, reverse=True)
+ self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+ message.repeated_string.sort(sort_function=len_cmp)
+ self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+ message.repeated_string.sort(cmp=len_cmp, reverse=True)
+ self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+
+ def testParsingMerge(self):
+ """Check the merge behavior when a required or optional field appears
+ multiple times in the input."""
+ messages = [
+ unittest_pb2.TestAllTypes(),
+ unittest_pb2.TestAllTypes(),
+ unittest_pb2.TestAllTypes() ]
+ messages[0].optional_int32 = 1
+ messages[1].optional_int64 = 2
+ messages[2].optional_int32 = 3
+ messages[2].optional_string = 'hello'
+
+ merged_message = unittest_pb2.TestAllTypes()
+ merged_message.optional_int32 = 3
+ merged_message.optional_int64 = 2
+ merged_message.optional_string = 'hello'
+
+ generator = unittest_pb2.TestParsingMerge.RepeatedFieldsGenerator()
+ generator.field1.extend(messages)
+ generator.field2.extend(messages)
+ generator.field3.extend(messages)
+ generator.ext1.extend(messages)
+ generator.ext2.extend(messages)
+ generator.group1.add().field1.MergeFrom(messages[0])
+ generator.group1.add().field1.MergeFrom(messages[1])
+ generator.group1.add().field1.MergeFrom(messages[2])
+ generator.group2.add().field1.MergeFrom(messages[0])
+ generator.group2.add().field1.MergeFrom(messages[1])
+ generator.group2.add().field1.MergeFrom(messages[2])
+
+ data = generator.SerializeToString()
+ parsing_merge = unittest_pb2.TestParsingMerge()
+ parsing_merge.ParseFromString(data)
+
+ # Required and optional fields should be merged.
+ self.assertEqual(parsing_merge.required_all_types, merged_message)
+ self.assertEqual(parsing_merge.optional_all_types, merged_message)
+ self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types,
+ merged_message)
+ self.assertEqual(parsing_merge.Extensions[
+ unittest_pb2.TestParsingMerge.optional_ext],
+ merged_message)
+
+ # Repeated fields should not be merged.
+ self.assertEqual(len(parsing_merge.repeated_all_types), 3)
+ self.assertEqual(len(parsing_merge.repeatedgroup), 3)
+ self.assertEqual(len(parsing_merge.Extensions[
+ unittest_pb2.TestParsingMerge.repeated_ext]), 3)
+
+
+ def testSortEmptyRepeatedCompositeContainer(self):
+ """Exercise a scenario that has led to segfaults in the past.
+ """
+ m = unittest_pb2.TestAllTypes()
+ m.repeated_nested_message.sort()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/more_extensions.proto b/code/push/google/protobuf/internal/more_extensions.proto
new file mode 100644
index 0000000..e2d9701
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_extensions.proto
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+
+message TopLevelMessage {
+ optional ExtendedMessage submessage = 1;
+}
+
+
+message ExtendedMessage {
+ extensions 1 to max;
+}
+
+
+message ForeignMessage {
+ optional int32 foreign_message_int = 1;
+}
+
+
+extend ExtendedMessage {
+ optional int32 optional_int_extension = 1;
+ optional ForeignMessage optional_message_extension = 2;
+
+ repeated int32 repeated_int_extension = 3;
+ repeated ForeignMessage repeated_message_extension = 4;
+}
diff --git a/code/push/google/protobuf/internal/more_extensions_dynamic.proto b/code/push/google/protobuf/internal/more_extensions_dynamic.proto
new file mode 100644
index 0000000..df98ac4
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_extensions_dynamic.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// This file is used to test a corner case in the CPP implementation where the
+// generated C++ type is available for the extendee, but the extension is
+// defined in a file whose C++ type is not in the binary.
+
+
+import "google/protobuf/internal/more_extensions.proto";
+
+package google.protobuf.internal;
+
+message DynamicMessageType {
+ optional int32 a = 1;
+}
+
+extend ExtendedMessage {
+ optional int32 dynamic_int32_extension = 100;
+ optional DynamicMessageType dynamic_message_extension = 101;
+}
diff --git a/code/push/google/protobuf/internal/more_extensions_dynamic_pb2.py b/code/push/google/protobuf/internal/more_extensions_dynamic_pb2.py
new file mode 100644
index 0000000..b9d331f
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_extensions_dynamic_pb2.py
@@ -0,0 +1,77 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/internal/more_extensions_dynamic.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+
+import google.protobuf.internal.more_extensions_pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='google/protobuf/internal/more_extensions_dynamic.proto',
+ package='google.protobuf.internal',
+ serialized_pb='\n6google/protobuf/internal/more_extensions_dynamic.proto\x12\x18google.protobuf.internal\x1a.google/protobuf/internal/more_extensions.proto\"\x1f\n\x12\x44ynamicMessageType\x12\t\n\x01\x61\x18\x01 \x01(\x05:J\n\x17\x64ynamic_int32_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x64 \x01(\x05:z\n\x19\x64ynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x65 \x01(\x0b\x32,.google.protobuf.internal.DynamicMessageType')
+
+
+DYNAMIC_INT32_EXTENSION_FIELD_NUMBER = 100
+dynamic_int32_extension = _descriptor.FieldDescriptor(
+ name='dynamic_int32_extension', full_name='google.protobuf.internal.dynamic_int32_extension', index=0,
+ number=100, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+DYNAMIC_MESSAGE_EXTENSION_FIELD_NUMBER = 101
+dynamic_message_extension = _descriptor.FieldDescriptor(
+ name='dynamic_message_extension', full_name='google.protobuf.internal.dynamic_message_extension', index=1,
+ number=101, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+
+
+_DYNAMICMESSAGETYPE = _descriptor.Descriptor(
+ name='DynamicMessageType',
+ full_name='google.protobuf.internal.DynamicMessageType',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='a', full_name='google.protobuf.internal.DynamicMessageType.a', index=0,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=132,
+ serialized_end=163,
+)
+
+DESCRIPTOR.message_types_by_name['DynamicMessageType'] = _DYNAMICMESSAGETYPE
+
+class DynamicMessageType(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _DYNAMICMESSAGETYPE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.internal.DynamicMessageType)
+
+google.protobuf.internal.more_extensions_pb2.ExtendedMessage.RegisterExtension(dynamic_int32_extension)
+dynamic_message_extension.message_type = _DYNAMICMESSAGETYPE
+google.protobuf.internal.more_extensions_pb2.ExtendedMessage.RegisterExtension(dynamic_message_extension)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/code/push/google/protobuf/internal/more_extensions_pb2.py b/code/push/google/protobuf/internal/more_extensions_pb2.py
new file mode 100644
index 0000000..03594bb
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_extensions_pb2.py
@@ -0,0 +1,159 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/internal/more_extensions.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='google/protobuf/internal/more_extensions.proto',
+ package='google.protobuf.internal',
+ serialized_pb='\n.google/protobuf/internal/more_extensions.proto\x12\x18google.protobuf.internal\"P\n\x0fTopLevelMessage\x12=\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessage\"\x1b\n\x0f\x45xtendedMessage*\x08\x08\x01\x10\x80\x80\x80\x80\x02\"-\n\x0e\x46oreignMessage\x12\x1b\n\x13\x66oreign_message_int\x18\x01 \x01(\x05:I\n\x16optional_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x01 \x01(\x05:w\n\x1aoptional_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x02 \x01(\x0b\x32(.google.protobuf.internal.ForeignMessage:I\n\x16repeated_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x03 \x03(\x05:w\n\x1arepeated_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x04 \x03(\x0b\x32(.google.protobuf.internal.ForeignMessage')
+
+
+OPTIONAL_INT_EXTENSION_FIELD_NUMBER = 1
+optional_int_extension = _descriptor.FieldDescriptor(
+ name='optional_int_extension', full_name='google.protobuf.internal.optional_int_extension', index=0,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+OPTIONAL_MESSAGE_EXTENSION_FIELD_NUMBER = 2
+optional_message_extension = _descriptor.FieldDescriptor(
+ name='optional_message_extension', full_name='google.protobuf.internal.optional_message_extension', index=1,
+ number=2, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+REPEATED_INT_EXTENSION_FIELD_NUMBER = 3
+repeated_int_extension = _descriptor.FieldDescriptor(
+ name='repeated_int_extension', full_name='google.protobuf.internal.repeated_int_extension', index=2,
+ number=3, type=5, cpp_type=1, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+REPEATED_MESSAGE_EXTENSION_FIELD_NUMBER = 4
+repeated_message_extension = _descriptor.FieldDescriptor(
+ name='repeated_message_extension', full_name='google.protobuf.internal.repeated_message_extension', index=3,
+ number=4, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+
+
+_TOPLEVELMESSAGE = _descriptor.Descriptor(
+ name='TopLevelMessage',
+ full_name='google.protobuf.internal.TopLevelMessage',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='submessage', full_name='google.protobuf.internal.TopLevelMessage.submessage', index=0,
+ number=1, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=76,
+ serialized_end=156,
+)
+
+
+_EXTENDEDMESSAGE = _descriptor.Descriptor(
+ name='ExtendedMessage',
+ full_name='google.protobuf.internal.ExtendedMessage',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1, 536870912), ],
+ serialized_start=158,
+ serialized_end=185,
+)
+
+
+_FOREIGNMESSAGE = _descriptor.Descriptor(
+ name='ForeignMessage',
+ full_name='google.protobuf.internal.ForeignMessage',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='foreign_message_int', full_name='google.protobuf.internal.ForeignMessage.foreign_message_int', index=0,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=187,
+ serialized_end=232,
+)
+
+_TOPLEVELMESSAGE.fields_by_name['submessage'].message_type = _EXTENDEDMESSAGE
+DESCRIPTOR.message_types_by_name['TopLevelMessage'] = _TOPLEVELMESSAGE
+DESCRIPTOR.message_types_by_name['ExtendedMessage'] = _EXTENDEDMESSAGE
+DESCRIPTOR.message_types_by_name['ForeignMessage'] = _FOREIGNMESSAGE
+
+class TopLevelMessage(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _TOPLEVELMESSAGE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.internal.TopLevelMessage)
+
+class ExtendedMessage(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _EXTENDEDMESSAGE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.internal.ExtendedMessage)
+
+class ForeignMessage(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FOREIGNMESSAGE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.internal.ForeignMessage)
+
+ExtendedMessage.RegisterExtension(optional_int_extension)
+optional_message_extension.message_type = _FOREIGNMESSAGE
+ExtendedMessage.RegisterExtension(optional_message_extension)
+ExtendedMessage.RegisterExtension(repeated_int_extension)
+repeated_message_extension.message_type = _FOREIGNMESSAGE
+ExtendedMessage.RegisterExtension(repeated_message_extension)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/code/push/google/protobuf/internal/more_messages.proto b/code/push/google/protobuf/internal/more_messages.proto
new file mode 100644
index 0000000..c701b44
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_messages.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+// A message where tag numbers are listed out of order, to allow us to test our
+// canonicalization of serialized output, which should always be in tag order.
+// We also mix in some extensions for extra fun.
+message OutOfOrderFields {
+ optional sint32 optional_sint32 = 5;
+ extensions 4 to 4;
+ optional uint32 optional_uint32 = 3;
+ extensions 2 to 2;
+ optional int32 optional_int32 = 1;
+};
+
+
+extend OutOfOrderFields {
+ optional uint64 optional_uint64 = 4;
+ optional int64 optional_int64 = 2;
+}
diff --git a/code/push/google/protobuf/internal/more_messages_pb2.py b/code/push/google/protobuf/internal/more_messages_pb2.py
new file mode 100644
index 0000000..41f6ba3
--- /dev/null
+++ b/code/push/google/protobuf/internal/more_messages_pb2.py
@@ -0,0 +1,89 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/internal/more_messages.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='google/protobuf/internal/more_messages.proto',
+ package='google.protobuf.internal',
+ serialized_pb='\n,google/protobuf/internal/more_messages.proto\x12\x18google.protobuf.internal\"h\n\x10OutOfOrderFields\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05*\x04\x08\x04\x10\x05*\x04\x08\x02\x10\x03:C\n\x0foptional_uint64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x04 \x01(\x04:B\n\x0eoptional_int64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x02 \x01(\x03')
+
+
+OPTIONAL_UINT64_FIELD_NUMBER = 4
+optional_uint64 = _descriptor.FieldDescriptor(
+ name='optional_uint64', full_name='google.protobuf.internal.optional_uint64', index=0,
+ number=4, type=4, cpp_type=4, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+OPTIONAL_INT64_FIELD_NUMBER = 2
+optional_int64 = _descriptor.FieldDescriptor(
+ name='optional_int64', full_name='google.protobuf.internal.optional_int64', index=1,
+ number=2, type=3, cpp_type=2, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=True, extension_scope=None,
+ options=None)
+
+
+_OUTOFORDERFIELDS = _descriptor.Descriptor(
+ name='OutOfOrderFields',
+ full_name='google.protobuf.internal.OutOfOrderFields',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='optional_sint32', full_name='google.protobuf.internal.OutOfOrderFields.optional_sint32', index=0,
+ number=5, type=17, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='optional_uint32', full_name='google.protobuf.internal.OutOfOrderFields.optional_uint32', index=1,
+ number=3, type=13, cpp_type=3, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ _descriptor.FieldDescriptor(
+ name='optional_int32', full_name='google.protobuf.internal.OutOfOrderFields.optional_int32', index=2,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(4, 5), (2, 3), ],
+ serialized_start=74,
+ serialized_end=178,
+)
+
+DESCRIPTOR.message_types_by_name['OutOfOrderFields'] = _OUTOFORDERFIELDS
+
+class OutOfOrderFields(_message.Message):
+ __metaclass__ = _reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _OUTOFORDERFIELDS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.internal.OutOfOrderFields)
+
+OutOfOrderFields.RegisterExtension(optional_uint64)
+OutOfOrderFields.RegisterExtension(optional_int64)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/code/push/google/protobuf/internal/python_message.py b/code/push/google/protobuf/internal/python_message.py
new file mode 100644
index 0000000..b006434
--- /dev/null
+++ b/code/push/google/protobuf/internal/python_message.py
@@ -0,0 +1,1150 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This code is meant to work on Python 2.4 and above only.
+#
+# TODO(robinson): Helpers for verbose, common checks like seeing if a
+# descriptor's cpp_type is CPPTYPE_MESSAGE.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+import copy_reg
+import struct
+import weakref
+
+# We use "as" to avoid name collisions with variables.
+from push.google.protobuf.internal import containers
+from push.google.protobuf.internal import decoder
+from push.google.protobuf.internal import encoder
+from push.google.protobuf.internal import enum_type_wrapper
+from push.google.protobuf.internal import message_listener as message_listener_mod
+from push.google.protobuf.internal import type_checkers
+from push.google.protobuf.internal import wire_format
+from push.google.protobuf import descriptor as descriptor_mod
+from push.google.protobuf import message as message_mod
+from push.google.protobuf import text_format
+
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+def NewMessage(bases, descriptor, dictionary):
+ _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+ _AddSlots(descriptor, dictionary)
+ return bases
+
+
+def InitMessage(descriptor, cls):
+ cls._decoders_by_tag = {}
+ cls._extensions_by_name = {}
+ cls._extensions_by_number = {}
+ if (descriptor.has_options and
+ descriptor.GetOptions().message_set_wire_format):
+ cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+ decoder.MessageSetItemDecoder(cls._extensions_by_number))
+
+ # Attach stuff to each FieldDescriptor for quick lookup later on.
+ for field in descriptor.fields:
+ _AttachFieldHelpers(cls, field)
+
+ _AddEnumValues(descriptor, cls)
+ _AddInitMethod(descriptor, cls)
+ _AddPropertiesForFields(descriptor, cls)
+ _AddPropertiesForExtensions(descriptor, cls)
+ _AddStaticMethods(cls)
+ _AddMessageMethods(descriptor, cls)
+ _AddPrivateHelperMethods(cls)
+ copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+# Stateless helpers for GeneratedProtocolMessageType below.
+# Outside clients should not access these directly.
+#
+# I opted not to make any of these methods on the metaclass, to make it more
+# clear that I'm not really using any state there and to keep clients from
+# thinking that they have direct access to these construction helpers.
+
+
+def _PropertyName(proto_field_name):
+ """Returns the name of the public property attribute which
+ clients can use to get and (in some cases) set the value
+ of a protocol message field.
+
+ Args:
+ proto_field_name: The protocol message field name, exactly
+ as it appears (or would appear) in a .proto file.
+ """
+ # TODO(robinson): Escape Python keywords (e.g., yield), and test this support.
+ # nnorwitz makes my day by writing:
+ # """
+ # FYI. See the keyword module in the stdlib. This could be as simple as:
+ #
+ # if keyword.iskeyword(proto_field_name):
+ # return proto_field_name + "_"
+ # return proto_field_name
+ # """
+ # Kenton says: The above is a BAD IDEA. People rely on being able to use
+ # getattr() and setattr() to reflectively manipulate field values. If we
+ # rename the properties, then every such user has to also make sure to apply
+ # the same transformation. Note that currently if you name a field "yield",
+ # you can still access it just fine using getattr/setattr -- it's not even
+ # that cumbersome to do so.
+ # TODO(kenton): Remove this method entirely if/when everyone agrees with my
+ # position.
+ return proto_field_name
+
+
+def _VerifyExtensionHandle(message, extension_handle):
+ """Verify that the given extension handle is valid."""
+
+ if not isinstance(extension_handle, _FieldDescriptor):
+ raise KeyError('HasExtension() expects an extension handle, got: %s' %
+ extension_handle)
+
+ if not extension_handle.is_extension:
+ raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
+
+ if not extension_handle.containing_type:
+ raise KeyError('"%s" is missing a containing_type.'
+ % extension_handle.full_name)
+
+ if extension_handle.containing_type is not message.DESCRIPTOR:
+ raise KeyError('Extension "%s" extends message type "%s", but this '
+ 'message is of type "%s".' %
+ (extension_handle.full_name,
+ extension_handle.containing_type.full_name,
+ message.DESCRIPTOR.full_name))
+
+
+def _AddSlots(message_descriptor, dictionary):
+ """Adds a __slots__ entry to dictionary, containing the names of all valid
+ attributes for this message type.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__slots__'] = ['_cached_byte_size',
+ '_cached_byte_size_dirty',
+ '_fields',
+ '_unknown_fields',
+ '_is_present_in_parent',
+ '_listener',
+ '_listener_for_children',
+ '__weakref__']
+
+
+def _IsMessageSetExtension(field):
+ return (field.is_extension and
+ field.containing_type.has_options and
+ field.containing_type.GetOptions().message_set_wire_format and
+ field.type == _FieldDescriptor.TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == _FieldDescriptor.LABEL_OPTIONAL)
+
+
+def _AttachFieldHelpers(cls, field_descriptor):
+ is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
+ is_packed = (field_descriptor.has_options and
+ field_descriptor.GetOptions().packed)
+
+ if _IsMessageSetExtension(field_descriptor):
+ field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
+ sizer = encoder.MessageSetItemSizer(field_descriptor.number)
+ else:
+ field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+ sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+
+ field_descriptor._encoder = field_encoder
+ field_descriptor._sizer = sizer
+ field_descriptor._default_constructor = _DefaultValueConstructorForField(
+ field_descriptor)
+
+ def AddDecoder(wiretype, is_packed):
+ tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+ cls._decoders_by_tag[tag_bytes] = (
+ type_checkers.TYPE_TO_DECODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed,
+ field_descriptor, field_descriptor._default_constructor))
+
+ AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
+ False)
+
+ if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
+ # To support wire compatibility of adding packed = true, add a decoder for
+ # packed values regardless of the field's options.
+ AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+
+
+def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddEnumValues(descriptor, cls):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Also exporting a class-level object that can name enum values.
+
+ Args:
+ descriptor: Descriptor object for this message type.
+ cls: Class we're constructing for this message type.
+ """
+ for enum_type in descriptor.enum_types:
+ setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type))
+ for enum_value in enum_type.values:
+ setattr(cls, enum_value.name, enum_value.number)
+
+
+def _DefaultValueConstructorForField(field):
+ """Returns a function which returns a default value for a field.
+
+ Args:
+ field: FieldDescriptor object for this field.
+
+ The returned function has one argument:
+ message: Message instance containing this field, or a weakref proxy
+ of same.
+
+ That function in turn returns a default value for this field. The default
+ value may refer back to |message| via a weak reference.
+ """
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ if field.has_default_value and field.default_value != []:
+ raise ValueError('Repeated field default value not empty list: %s' % (
+ field.default_value))
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # We can't look at _concrete_class yet since it might not have
+ # been set. (Depends on order in which we initialize the classes).
+ message_type = field.message_type
+ def MakeRepeatedMessageDefault(message):
+ return containers.RepeatedCompositeFieldContainer(
+ message._listener_for_children, field.message_type)
+ return MakeRepeatedMessageDefault
+ else:
+ type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+ def MakeRepeatedScalarDefault(message):
+ return containers.RepeatedScalarFieldContainer(
+ message._listener_for_children, type_checker)
+ return MakeRepeatedScalarDefault
+
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # _concrete_class may not yet be initialized.
+ message_type = field.message_type
+ def MakeSubMessageDefault(message):
+ result = message_type._concrete_class()
+ result._SetListener(message._listener_for_children)
+ return result
+ return MakeSubMessageDefault
+
+ def MakeScalarDefault(message):
+ # TODO(protobuf-team): This may be broken since there may not be
+ # default_value. Combine with has_default_value somehow.
+ return field.default_value
+ return MakeScalarDefault
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+ fields = message_descriptor.fields
+ def init(self, **kwargs):
+ self._cached_byte_size = 0
+ self._cached_byte_size_dirty = len(kwargs) > 0
+ self._fields = {}
+ # _unknown_fields is () when empty for efficiency, and will be turned into
+ # a list if fields are added.
+ self._unknown_fields = ()
+ self._is_present_in_parent = False
+ self._listener = message_listener_mod.NullMessageListener()
+ self._listener_for_children = _Listener(self)
+ for field_name, field_value in kwargs.iteritems():
+ field = _GetFieldByName(message_descriptor, field_name)
+ if field is None:
+ raise TypeError("%s() got an unexpected keyword argument '%s'" %
+ (message_descriptor.name, field_name))
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ copy = field._default_constructor(self)
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
+ for val in field_value:
+ copy.add().MergeFrom(val)
+ else: # Scalar
+ copy.extend(field_value)
+ self._fields[field] = copy
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ copy = field._default_constructor(self)
+ copy.MergeFrom(field_value)
+ self._fields[field] = copy
+ else:
+ setattr(self, field_name, field_value)
+
+ init.__module__ = None
+ init.__doc__ = None
+ cls.__init__ = init
+
+
+def _GetFieldByName(message_descriptor, field_name):
+ """Returns a field descriptor by field name.
+
+ Args:
+ message_descriptor: A Descriptor describing all fields in message.
+ field_name: The name of the field to retrieve.
+ Returns:
+ The field descriptor associated with the field name.
+ """
+ try:
+ return message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+
+def _AddPropertiesForFields(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ for field in descriptor.fields:
+ _AddPropertiesForField(field, cls)
+
+ if descriptor.is_extendable:
+ # _ExtensionDict is just an adaptor with no state so we allocate a new one
+ # every time it is accessed.
+ cls.Extensions = property(lambda self: _ExtensionDict(self))
+
+
+def _AddPropertiesForField(field, cls):
+ """Adds a public property for a protocol message field.
+ Clients can use this property to get and (in the case
+ of non-repeated scalar fields) directly set the value
+ of a protocol message field.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # Catch it if we add other types that we should
+ # handle specially here.
+ assert _FieldDescriptor.MAX_CPPTYPE == 10
+
+ constant_name = field.name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, field.number)
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ _AddPropertiesForRepeatedField(field, cls)
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ _AddPropertiesForNonRepeatedCompositeField(field, cls)
+ else:
+ _AddPropertiesForNonRepeatedScalarField(field, cls)
+
+
+def _AddPropertiesForRepeatedField(field, cls):
+ """Adds a public property for a "repeated" protocol message field. Clients
+ can use this property to get the value of the field, which will be either a
+ _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see
+ below).
+
+ Note that when clients add values to these containers, we perform
+ type-checking in the case of repeated scalar fields, and we also set any
+ necessary "has" bits as a side-effect.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedScalarField(field, cls):
+ """Adds a public property for a nonrepeated, scalar protocol message field.
+ Clients can use this property to get and directly set the value of the field.
+ Note that when the client sets the value of a field by using this property,
+ all necessary "has" bits are set as a side-effect, and we also perform
+ type-checking.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+ type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+ default_value = field.default_value
+ valid_values = set()
+
+ def getter(self):
+ # TODO(protobuf-team): This may be broken since there may not be
+ # default_value. Combine with has_default_value somehow.
+ return self._fields.get(field, default_value)
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+ def setter(self, new_value):
+ type_checker.CheckValue(new_value)
+ self._fields[field] = new_value
+ # Check _cached_byte_size_dirty inline to improve performance, since scalar
+ # setters are called frequently.
+ if not self._cached_byte_size_dirty:
+ self._Modified()
+
+ setter.__module__ = None
+ setter.__doc__ = 'Setter for %s.' % proto_field_name
+
+ # Add a property to encapsulate the getter/setter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedCompositeField(field, cls):
+ """Adds a public property for a nonrepeated, composite protocol message field.
+ A composite field is a "group" or "message" field.
+
+ Clients can use this property to get the value of the field, but cannot
+ assign to the property directly.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # TODO(robinson): Remove duplication with similar method
+ # for non-repeated scalars.
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+
+ # TODO(komarek): Can anyone explain to me why we cache the message_type this
+ # way, instead of referring to field.message_type inside of getter(self)?
+ # What if someone sets message_type later on (which makes for simpler
+ # dyanmic proto descriptor and class creation code).
+ message_type = field.message_type
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = message_type._concrete_class() # use field.message_type?
+ field_value._SetListener(self._listener_for_children)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to composite field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ # Add a property to encapsulate the getter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForExtensions(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, extension_field.number)
+
+
+def _AddStaticMethods(cls):
+ # TODO(robinson): This probably needs to be thread-safe(?)
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ _AttachFieldHelpers(cls, extension_handle)
+
+ # Try to insert our extension, failing if an extension with the same number
+ # already exists.
+ actual_handle = cls._extensions_by_number.setdefault(
+ extension_handle.number, extension_handle)
+ if actual_handle is not extension_handle:
+ raise AssertionError(
+ 'Extensions "%s" and "%s" both try to extend message type "%s" with '
+ 'field number %d.' %
+ (extension_handle.full_name, actual_handle.full_name,
+ cls.DESCRIPTOR.full_name, extension_handle.number))
+
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ handle = extension_handle # avoid line wrapping
+ if _IsMessageSetExtension(handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(s):
+ message = cls()
+ message.MergeFromString(s)
+ return message
+ cls.FromString = staticmethod(FromString)
+
+
+def _IsPresent(item):
+ """Given a (FieldDescriptor, value) tuple from _fields, return true if the
+ value should be included in the list returned by ListFields()."""
+
+ if item[0].label == _FieldDescriptor.LABEL_REPEATED:
+ return bool(item[1])
+ elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ return item[1]._is_present_in_parent
+ else:
+ return True
+
+
+def _AddListFieldsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ListFields(self):
+ all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
+ all_fields.sort(key = lambda item: item[0].number)
+ return all_fields
+
+ cls.ListFields = ListFields
+
+
+def _AddHasFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ singular_fields = {}
+ for field in message_descriptor.fields:
+ if field.label != _FieldDescriptor.LABEL_REPEATED:
+ singular_fields[field.name] = field
+
+ def HasField(self, field_name):
+ try:
+ field = singular_fields[field_name]
+ except KeyError:
+ raise ValueError(
+ 'Protocol message has no singular "%s" field.' % field_name)
+
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(field)
+ return value is not None and value._is_present_in_parent
+ else:
+ return field in self._fields
+ cls.HasField = HasField
+
+
+def _AddClearFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearField(self, field_name):
+ try:
+ field = message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+ if field in self._fields:
+ # Note: If the field is a sub-message, its listener will still point
+ # at us. That's fine, because the worst than can happen is that it
+ # will call _Modified() and invalidate our byte size. Big deal.
+ del self._fields[field]
+
+ # Always call _Modified() -- even if nothing was changed, this is
+ # a mutating method, and thus calling it should cause the field to become
+ # present in the parent message.
+ self._Modified()
+
+ cls.ClearField = ClearField
+
+
+def _AddClearExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+
+ # Similar to ClearField(), above.
+ if extension_handle in self._fields:
+ del self._fields[extension_handle]
+ self._Modified()
+ cls.ClearExtension = ClearExtension
+
+
+def _AddClearMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def Clear(self):
+ # Clear fields.
+ self._fields = {}
+ self._unknown_fields = ()
+ self._Modified()
+ cls.Clear = Clear
+
+
+def _AddHasExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def HasExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ raise KeyError('"%s" is repeated.' % extension_handle.full_name)
+
+ if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(extension_handle)
+ return value is not None and value._is_present_in_parent
+ else:
+ return extension_handle in self._fields
+ cls.HasExtension = HasExtension
+
+
+def _AddEqualsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __eq__(self, other):
+ if (not isinstance(other, message_mod.Message) or
+ other.DESCRIPTOR != self.DESCRIPTOR):
+ return False
+
+ if self is other:
+ return True
+
+ if not self.ListFields() == other.ListFields():
+ return False
+
+ # Sort unknown fields because their order shouldn't affect equality test.
+ unknown_fields = list(self._unknown_fields)
+ unknown_fields.sort()
+ other_unknown_fields = list(other._unknown_fields)
+ other_unknown_fields.sort()
+
+ return unknown_fields == other_unknown_fields
+
+ cls.__eq__ = __eq__
+
+
+def _AddStrMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __str__(self):
+ return text_format.MessageToString(self)
+ cls.__str__ = __str__
+
+
+def _AddUnicodeMethod(unused_message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def __unicode__(self):
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+ cls.__unicode__ = __unicode__
+
+
+def _AddSetListenerMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def SetListener(self, listener):
+ if listener is None:
+ self._listener = message_listener_mod.NullMessageListener()
+ else:
+ self._listener = listener
+ cls._SetListener = SetListener
+
+
+def _BytesForNonRepeatedElement(value, field_number, field_type):
+ """Returns the number of bytes needed to serialize a non-repeated element.
+ The returned byte count includes space for tag information and any
+ other additional space associated with serializing value.
+
+ Args:
+ value: Value we're serializing.
+ field_number: Field number of this value. (Since the field number
+ is stored as part of a varint-encoded tag, this has an impact
+ on the total bytes required to serialize the value).
+ field_type: The type of the field. One of the TYPE_* constants
+ within FieldDescriptor.
+ """
+ try:
+ fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
+ return fn(field_number, value)
+ except KeyError:
+ raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
+
+
+def _AddByteSizeMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ByteSize(self):
+ if not self._cached_byte_size_dirty:
+ return self._cached_byte_size
+
+ size = 0
+ for field_descriptor, field_value in self.ListFields():
+ size += field_descriptor._sizer(field_value)
+
+ for tag_bytes, value_bytes in self._unknown_fields:
+ size += len(tag_bytes) + len(value_bytes)
+
+ self._cached_byte_size = size
+ self._cached_byte_size_dirty = False
+ self._listener_for_children.dirty = False
+ return size
+
+ cls.ByteSize = ByteSize
+
+
+def _AddSerializeToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializeToString(self):
+ # Check if the message has all of its required fields set.
+ errors = []
+ if not self.IsInitialized():
+ raise message_mod.EncodeError(
+ 'Message %s is missing required fields: %s' % (
+ self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
+ return self.SerializePartialToString()
+ cls.SerializeToString = SerializeToString
+
+
+def _AddSerializePartialToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializePartialToString(self):
+ out = StringIO()
+ self._InternalSerialize(out.write)
+ return out.getvalue()
+ cls.SerializePartialToString = SerializePartialToString
+
+ def InternalSerialize(self, write_bytes):
+ for field_descriptor, field_value in self.ListFields():
+ field_descriptor._encoder(write_bytes, field_value)
+ for tag_bytes, value_bytes in self._unknown_fields:
+ write_bytes(tag_bytes)
+ write_bytes(value_bytes)
+ cls._InternalSerialize = InternalSerialize
+
+
+def _AddMergeFromStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def MergeFromString(self, serialized):
+ length = len(serialized)
+ try:
+ if self._InternalParse(serialized, 0, length) != length:
+ # The only reason _InternalParse would return early is if it
+ # encountered an end-group tag.
+ raise message_mod.DecodeError('Unexpected end-group tag.')
+ except IndexError:
+ raise message_mod.DecodeError('Truncated message.')
+ except struct.error, e:
+ raise message_mod.DecodeError(e)
+ return length # Return this for legacy reasons.
+ cls.MergeFromString = MergeFromString
+
+ local_ReadTag = decoder.ReadTag
+ local_SkipField = decoder.SkipField
+ decoders_by_tag = cls._decoders_by_tag
+
+ def InternalParse(self, buffer, pos, end):
+ self._Modified()
+ field_dict = self._fields
+ unknown_field_list = self._unknown_fields
+ while pos != end:
+ (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
+ field_decoder = decoders_by_tag.get(tag_bytes)
+ if field_decoder is None:
+ value_start_pos = new_pos
+ new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
+ if new_pos == -1:
+ return pos
+ if not unknown_field_list:
+ unknown_field_list = self._unknown_fields = []
+ unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos]))
+ pos = new_pos
+ else:
+ pos = field_decoder(buffer, new_pos, end, self, field_dict)
+ return pos
+ cls._InternalParse = InternalParse
+
+
+def _AddIsInitializedMethod(message_descriptor, cls):
+ """Adds the IsInitialized and FindInitializationError methods to the
+ protocol message class."""
+
+ required_fields = [field for field in message_descriptor.fields
+ if field.label == _FieldDescriptor.LABEL_REQUIRED]
+
+ def IsInitialized(self, errors=None):
+ """Checks if all required fields of a message are set.
+
+ Args:
+ errors: A list which, if provided, will be populated with the field
+ paths of all missing required fields.
+
+ Returns:
+ True iff the specified message has all required fields set.
+ """
+
+ # Performance is critical so we avoid HasField() and ListFields().
+
+ for field in required_fields:
+ if (field not in self._fields or
+ (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
+ not self._fields[field]._is_present_in_parent)):
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ for field, value in self._fields.iteritems():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for element in value:
+ if not element.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+ elif value._is_present_in_parent and not value.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ return True
+
+ cls.IsInitialized = IsInitialized
+
+ def FindInitializationErrors(self):
+ """Finds required fields which are not initialized.
+
+ Returns:
+ A list of strings. Each string is a path to an uninitialized field from
+ the top-level message, e.g. "foo.bar[5].baz".
+ """
+
+ errors = [] # simplify things
+
+ for field in required_fields:
+ if not self.HasField(field.name):
+ errors.append(field.name)
+
+ for field, value in self.ListFields():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.is_extension:
+ name = "(%s)" % field.full_name
+ else:
+ name = field.name
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for i in xrange(len(value)):
+ element = value[i]
+ prefix = "%s[%d]." % (name, i)
+ sub_errors = element.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+ else:
+ prefix = name + "."
+ sub_errors = value.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+
+ return errors
+
+ cls.FindInitializationErrors = FindInitializationErrors
+
+
+def _AddMergeFromMethod(cls):
+ LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
+ CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s." % (cls.__name__, type(msg).__name__))
+
+ assert msg is not self
+ self._Modified()
+
+ fields = self._fields
+
+ for field, value in msg._fields.iteritems():
+ if field.label == LABEL_REPEATED:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ elif field.cpp_type == CPPTYPE_MESSAGE:
+ if value._is_present_in_parent:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ else:
+ self._fields[field] = value
+
+ if msg._unknown_fields:
+ if not self._unknown_fields:
+ self._unknown_fields = []
+ self._unknown_fields.extend(msg._unknown_fields)
+
+ cls.MergeFrom = MergeFrom
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds implementations of all Message methods to cls."""
+ _AddListFieldsMethod(message_descriptor, cls)
+ _AddHasFieldMethod(message_descriptor, cls)
+ _AddClearFieldMethod(message_descriptor, cls)
+ if message_descriptor.is_extendable:
+ _AddClearExtensionMethod(cls)
+ _AddHasExtensionMethod(cls)
+ _AddClearMethod(message_descriptor, cls)
+ _AddEqualsMethod(message_descriptor, cls)
+ _AddStrMethod(message_descriptor, cls)
+ _AddUnicodeMethod(message_descriptor, cls)
+ _AddSetListenerMethod(cls)
+ _AddByteSizeMethod(message_descriptor, cls)
+ _AddSerializeToStringMethod(message_descriptor, cls)
+ _AddSerializePartialToStringMethod(message_descriptor, cls)
+ _AddMergeFromStringMethod(message_descriptor, cls)
+ _AddIsInitializedMethod(message_descriptor, cls)
+ _AddMergeFromMethod(cls)
+
+
+def _AddPrivateHelperMethods(cls):
+ """Adds implementation of private helper methods to cls."""
+
+ def Modified(self):
+ """Sets the _cached_byte_size_dirty bit to true,
+ and propagates this to our listener iff this was a state change.
+ """
+
+ # Note: Some callers check _cached_byte_size_dirty before calling
+ # _Modified() as an extra optimization. So, if this method is ever
+ # changed such that it does stuff even when _cached_byte_size_dirty is
+ # already true, the callers need to be updated.
+ if not self._cached_byte_size_dirty:
+ self._cached_byte_size_dirty = True
+ self._listener_for_children.dirty = True
+ self._is_present_in_parent = True
+ self._listener.Modified()
+
+ cls._Modified = Modified
+ cls.SetInParent = Modified
+
+
+class _Listener(object):
+
+ """MessageListener implementation that a parent message registers with its
+ child message.
+
+ In order to support semantics like:
+
+ foo.bar.baz.qux = 23
+ assert foo.HasField('bar')
+
+ ...child objects must have back references to their parents.
+ This helper class is at the heart of this support.
+ """
+
+ def __init__(self, parent_message):
+ """Args:
+ parent_message: The message whose _Modified() method we should call when
+ we receive Modified() messages.
+ """
+ # This listener establishes a back reference from a child (contained) object
+ # to its parent (containing) object. We make this a weak reference to avoid
+ # creating cyclic garbage when the client finishes with the 'parent' object
+ # in the tree.
+ if isinstance(parent_message, weakref.ProxyType):
+ self._parent_message_weakref = parent_message
+ else:
+ self._parent_message_weakref = weakref.proxy(parent_message)
+
+ # As an optimization, we also indicate directly on the listener whether
+ # or not the parent message is dirty. This way we can avoid traversing
+ # up the tree in the common case.
+ self.dirty = False
+
+ def Modified(self):
+ if self.dirty:
+ return
+ try:
+ # Propagate the signal to our parents iff this is the first field set.
+ self._parent_message_weakref._Modified()
+ except ReferenceError:
+ # We can get here if a client has kept a reference to a child object,
+ # and is now setting a field on it, but the child's parent has been
+ # garbage-collected. This is not an error.
+ pass
+
+
+# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
+# TODO(robinson): Unify error handling of "unknown extension" crap.
+# TODO(robinson): Support iteritems()-style iteration over all
+# extensions with the "has" bits turned on?
+class _ExtensionDict(object):
+
+ """Dict-like container for supporting an indexable "Extensions"
+ field on proto instances.
+
+ Note that in all cases we expect extension handles to be
+ FieldDescriptors.
+ """
+
+ def __init__(self, extended_message):
+ """extended_message: Message instance for which we are the Extensions dict.
+ """
+
+ self._extended_message = extended_message
+
+ def __getitem__(self, extension_handle):
+ """Returns the current value of the given extension handle."""
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ result = self._extended_message._fields.get(extension_handle)
+ if result is not None:
+ return result
+
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ result = extension_handle._default_constructor(self._extended_message)
+ elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ result = extension_handle.message_type._concrete_class()
+ try:
+ result._SetListener(self._extended_message._listener_for_children)
+ except ReferenceError:
+ pass
+ else:
+ # Singular scalar -- just return the default without inserting into the
+ # dict.
+ return extension_handle.default_value
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ result = self._extended_message._fields.setdefault(
+ extension_handle, result)
+
+ return result
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+
+ my_fields = self._extended_message.ListFields()
+ other_fields = other._extended_message.ListFields()
+
+ # Get rid of non-extension fields.
+ my_fields = [ field for field in my_fields if field.is_extension ]
+ other_fields = [ field for field in other_fields if field.is_extension ]
+
+ return my_fields == other_fields
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ # Note that this is only meaningful for non-repeated, scalar extension
+ # fields. Note also that we may have to call _Modified() when we do
+ # successfully set a field this way, to set any necssary "has" bits in the
+ # ancestors of the extended message.
+ def __setitem__(self, extension_handle, value):
+ """If extension_handle specifies a non-repeated, scalar extension
+ field, sets the value of that field.
+ """
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
+ extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
+ raise TypeError(
+ 'Cannot assign to extension "%s" because it is a repeated or '
+ 'composite type.' % extension_handle.full_name)
+
+ # It's slightly wasteful to lookup the type checker each time,
+ # but we expect this to be a vanishingly uncommon case anyway.
+ type_checker = type_checkers.GetTypeChecker(
+ extension_handle.cpp_type, extension_handle.type)
+ type_checker.CheckValue(value)
+ self._extended_message._fields[extension_handle] = value
+ self._extended_message._Modified()
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_name.get(name, None)
diff --git a/code/push/google/protobuf/internal/reflection_cpp_generated_test.py b/code/push/google/protobuf/internal/reflection_cpp_generated_test.py
new file mode 100644
index 0000000..2a0a512
--- /dev/null
+++ b/code/push/google/protobuf/internal/reflection_cpp_generated_test.py
@@ -0,0 +1,91 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for reflection.py, which tests the generated C++ implementation."""
+
+__author__ = 'jasonh@google.com (Jason Hsueh)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+
+import unittest
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_dynamic_pb2
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal.reflection_test import *
+
+
+class ReflectionCppTest(unittest.TestCase):
+ def testImplementationSetting(self):
+ self.assertEqual('cpp', api_implementation.Type())
+
+ def testExtensionOfGeneratedTypeInDynamicFile(self):
+ """Tests that a file built dynamically can extend a generated C++ type.
+
+ The C++ implementation uses a DescriptorPool that has the generated
+ DescriptorPool as an underlay. Typically, a type can only find
+ extensions in its own pool. With the python C-extension, the generated C++
+ extendee may be available, but not the extension. This tests that the
+ C-extension implements the correct special handling to make such extensions
+ available.
+ """
+ pb1 = more_extensions_pb2.ExtendedMessage()
+ # Test that basic accessors work.
+ self.assertFalse(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertFalse(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+ pb1.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension] = 17
+ pb1.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a = 24
+ self.assertTrue(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertTrue(
+ pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+
+ # Now serialize the data and parse to a new message.
+ pb2 = more_extensions_pb2.ExtendedMessage()
+ pb2.MergeFromString(pb1.SerializeToString())
+
+ self.assertTrue(
+ pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+ self.assertTrue(
+ pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+ self.assertEqual(
+ 17, pb2.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension])
+ self.assertEqual(
+ 24,
+ pb2.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/reflection_test.py b/code/push/google/protobuf/internal/reflection_test.py
new file mode 100644
index 0000000..ed28646
--- /dev/null
+++ b/code/push/google/protobuf/internal/reflection_test.py
@@ -0,0 +1,2671 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for reflection.py, which also indirectly tests the output of the
+pure-Python protocol compiler.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import gc
+import operator
+import struct
+
+import unittest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal import more_messages_pb2
+from google.protobuf.internal import wire_format
+from google.protobuf.internal import test_util
+from google.protobuf.internal import decoder
+
+
+class _MiniDecoder(object):
+ """Decodes a stream of values from a string.
+
+ Once upon a time we actually had a class called decoder.Decoder. Then we
+ got rid of it during a redesign that made decoding much, much faster overall.
+ But a couple tests in this file used it to check that the serialized form of
+ a message was correct. So, this class implements just the methods that were
+ used by said tests, so that we don't have to rewrite the tests.
+ """
+
+ def __init__(self, bytes):
+ self._bytes = bytes
+ self._pos = 0
+
+ def ReadVarint(self):
+ result, self._pos = decoder._DecodeVarint(self._bytes, self._pos)
+ return result
+
+ ReadInt32 = ReadVarint
+ ReadInt64 = ReadVarint
+ ReadUInt32 = ReadVarint
+ ReadUInt64 = ReadVarint
+
+ def ReadSInt64(self):
+ return wire_format.ZigZagDecode(self.ReadVarint())
+
+ ReadSInt32 = ReadSInt64
+
+ def ReadFieldNumberAndWireType(self):
+ return wire_format.UnpackTag(self.ReadVarint())
+
+ def ReadFloat(self):
+ result = struct.unpack("".',
+ text_format.Merge, text, message)
+
+ text = 'RepeatedGroup: {'
+ self.assertRaisesWithMessage(
+ text_format.ParseError, '1:16 : Expected "}".',
+ text_format.Merge, text, message)
+
+ def testMergeEmptyGroup(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'OptionalGroup: {}'
+ text_format.Merge(text, message)
+ self.assertTrue(message.HasField('optionalgroup'))
+
+ message.Clear()
+
+ message = unittest_pb2.TestAllTypes()
+ text = 'OptionalGroup: <>'
+ text_format.Merge(text, message)
+ self.assertTrue(message.HasField('optionalgroup'))
+
+ def testMergeBadEnumValue(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_nested_enum: BARR'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+ 'has no value named BARR.'),
+ text_format.Merge, text, message)
+
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_nested_enum: 100'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+ 'has no value with number 100.'),
+ text_format.Merge, text, message)
+
+ def testMergeBadIntValue(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_int32: bork'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:17 : Couldn\'t parse integer: bork'),
+ text_format.Merge, text, message)
+
+ def testMergeStringFieldUnescape(self):
+ message = unittest_pb2.TestAllTypes()
+ text = r'''repeated_string: "\xf\x62"
+ repeated_string: "\\xf\\x62"
+ repeated_string: "\\\xf\\\x62"
+ repeated_string: "\\\\xf\\\\x62"
+ repeated_string: "\\\\\xf\\\\\x62"
+ repeated_string: "\x5cx20"'''
+ text_format.Merge(text, message)
+
+ SLASH = '\\'
+ self.assertEqual('\x0fb', message.repeated_string[0])
+ self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1])
+ self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2])
+ self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62',
+ message.repeated_string[3])
+ self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b',
+ message.repeated_string[4])
+ self.assertEqual(SLASH + 'x20', message.repeated_string[5])
+
+ def assertRaisesWithMessage(self, e_class, e, func, *args, **kwargs):
+ """Same as assertRaises, but also compares the exception message."""
+ if hasattr(e_class, '__name__'):
+ exc_name = e_class.__name__
+ else:
+ exc_name = str(e_class)
+
+ try:
+ func(*args, **kwargs)
+ except e_class as expr:
+ if str(expr) != e:
+ msg = '%s raised, but with wrong message: "%s" instead of "%s"'
+ raise self.failureException(msg % (exc_name,
+ str(expr).encode('string_escape'),
+ e.encode('string_escape')))
+ return
+ else:
+ raise self.failureException('%s not raised' % exc_name)
+
+
+class TokenizerTest(unittest.TestCase):
+
+ def testSimpleTokenCases(self):
+ text = ('identifier1:"string1"\n \n\n'
+ 'identifier2 : \n \n123 \n identifier3 :\'string\'\n'
+ 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
+ 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
+ 'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
+ 'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f '
+ 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' )
+ tokenizer = text_format._Tokenizer(text)
+ methods = [(tokenizer.ConsumeIdentifier, 'identifier1'),
+ ':',
+ (tokenizer.ConsumeString, 'string1'),
+ (tokenizer.ConsumeIdentifier, 'identifier2'),
+ ':',
+ (tokenizer.ConsumeInt32, 123),
+ (tokenizer.ConsumeIdentifier, 'identifier3'),
+ ':',
+ (tokenizer.ConsumeString, 'string'),
+ (tokenizer.ConsumeIdentifier, 'identifiER_4'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.1e+2),
+ (tokenizer.ConsumeIdentifier, 'ID5'),
+ ':',
+ (tokenizer.ConsumeFloat, -0.23),
+ (tokenizer.ConsumeIdentifier, 'ID6'),
+ ':',
+ (tokenizer.ConsumeString, 'aaaa\'bbbb'),
+ (tokenizer.ConsumeIdentifier, 'ID7'),
+ ':',
+ (tokenizer.ConsumeString, 'aa\"bb'),
+ (tokenizer.ConsumeIdentifier, 'ID8'),
+ ':',
+ '{',
+ (tokenizer.ConsumeIdentifier, 'A'),
+ ':',
+ (tokenizer.ConsumeFloat, float('inf')),
+ (tokenizer.ConsumeIdentifier, 'B'),
+ ':',
+ (tokenizer.ConsumeFloat, -float('inf')),
+ (tokenizer.ConsumeIdentifier, 'C'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'D'),
+ ':',
+ (tokenizer.ConsumeBool, False),
+ '}',
+ (tokenizer.ConsumeIdentifier, 'ID9'),
+ ':',
+ (tokenizer.ConsumeUint32, 22),
+ (tokenizer.ConsumeIdentifier, 'ID10'),
+ ':',
+ (tokenizer.ConsumeInt64, -111111111111111111),
+ (tokenizer.ConsumeIdentifier, 'ID11'),
+ ':',
+ (tokenizer.ConsumeInt32, -22),
+ (tokenizer.ConsumeIdentifier, 'ID12'),
+ ':',
+ (tokenizer.ConsumeUint64, 2222222222222222222),
+ (tokenizer.ConsumeIdentifier, 'ID13'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.23456),
+ (tokenizer.ConsumeIdentifier, 'ID14'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.2e+2),
+ (tokenizer.ConsumeIdentifier, 'false_bool'),
+ ':',
+ (tokenizer.ConsumeBool, False),
+ (tokenizer.ConsumeIdentifier, 'true_BOOL'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'true_bool1'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'false_BOOL1'),
+ ':',
+ (tokenizer.ConsumeBool, False)]
+
+ i = 0
+ while not tokenizer.AtEnd():
+ m = methods[i]
+ if type(m) == str:
+ token = tokenizer.token
+ self.assertEqual(token, m)
+ tokenizer.NextToken()
+ else:
+ self.assertEqual(m[1], m[0]())
+ i += 1
+
+ def testConsumeIntegers(self):
+ # This test only tests the failures in the integer parsing methods as well
+ # as the '0' special cases.
+ int64_max = (1 << 63) - 1
+ uint32_max = (1 << 32) - 1
+ text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64)
+ self.assertEqual(-1, tokenizer.ConsumeInt32())
+
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32)
+ self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64())
+
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64)
+ self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64())
+ self.assertTrue(tokenizer.AtEnd())
+
+ text = '-0 -0 0 0'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertEqual(0, tokenizer.ConsumeUint32())
+ self.assertEqual(0, tokenizer.ConsumeUint64())
+ self.assertEqual(0, tokenizer.ConsumeUint32())
+ self.assertEqual(0, tokenizer.ConsumeUint64())
+ self.assertTrue(tokenizer.AtEnd())
+
+ def testConsumeByteString(self):
+ text = '"string1\''
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = 'string1"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\xt"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\x"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ def testConsumeBool(self):
+ text = 'not-a-bool'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/type_checkers.py b/code/push/google/protobuf/internal/type_checkers.py
new file mode 100644
index 0000000..09bf5e4
--- /dev/null
+++ b/code/push/google/protobuf/internal/type_checkers.py
@@ -0,0 +1,286 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides type checking routines.
+
+This module defines type checking utilities in the forms of dictionaries:
+
+VALUE_CHECKERS: A dictionary of field types and a value validation object.
+TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
+ function.
+TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
+ function.
+FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
+ coresponding wire types.
+TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
+ function.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from push.google.protobuf.internal import decoder
+from push.google.protobuf.internal import encoder
+from push.google.protobuf.internal import wire_format
+from push.google.protobuf import descriptor
+
+_FieldDescriptor = descriptor.FieldDescriptor
+
+
+def GetTypeChecker(cpp_type, field_type):
+ """Returns a type checker for a message field of the specified types.
+
+ Args:
+ cpp_type: C++ type of the field (see descriptor.py).
+ field_type: Protocol message field type (see descriptor.py).
+
+ Returns:
+ An instance of TypeChecker which can be used to verify the types
+ of values assigned to a field of the specified type.
+ """
+ if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and
+ field_type == _FieldDescriptor.TYPE_STRING):
+ return UnicodeValueChecker()
+ return _VALUE_CHECKERS[cpp_type]
+
+
+# None of the typecheckers below make any attempt to guard against people
+# subclassing builtin types and doing weird things. We're not trying to
+# protect against malicious clients here, just people accidentally shooting
+# themselves in the foot in obvious ways.
+
+class TypeChecker(object):
+
+ """Type checker used to catch type errors as early as possible
+ when the client is setting scalar fields in protocol messages.
+ """
+
+ def __init__(self, *acceptable_types):
+ self._acceptable_types = acceptable_types
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, self._acceptable_types):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), self._acceptable_types))
+ raise TypeError(message)
+
+
+# IntValueChecker and its subclasses perform integer type-checks
+# and bounds-checks.
+class IntValueChecker(object):
+
+ """Checker used for integer fields. Performs type-check and range check."""
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, (int, long)):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), (int, long)))
+ raise TypeError(message)
+ if not self._MIN <= proposed_value <= self._MAX:
+ raise ValueError('Value out of range: %d' % proposed_value)
+
+
+class UnicodeValueChecker(object):
+
+ """Checker used for string fields."""
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, (str, unicode)):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), (str, unicode)))
+ raise TypeError(message)
+
+ # If the value is of type 'str' make sure that it is in 7-bit ASCII
+ # encoding.
+ if isinstance(proposed_value, str):
+ try:
+ unicode(proposed_value, 'ascii')
+ except UnicodeDecodeError:
+ raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII '
+ 'encoding. Non-ASCII strings must be converted to '
+ 'unicode objects before being added.' %
+ (proposed_value))
+
+
+class Int32ValueChecker(IntValueChecker):
+ # We're sure to use ints instead of longs here since comparison may be more
+ # efficient.
+ _MIN = -2147483648
+ _MAX = 2147483647
+
+
+class Uint32ValueChecker(IntValueChecker):
+ _MIN = 0
+ _MAX = (1 << 32) - 1
+
+
+class Int64ValueChecker(IntValueChecker):
+ _MIN = -(1 << 63)
+ _MAX = (1 << 63) - 1
+
+
+class Uint64ValueChecker(IntValueChecker):
+ _MIN = 0
+ _MAX = (1 << 64) - 1
+
+
+# Type-checkers for all scalar CPPTYPEs.
+_VALUE_CHECKERS = {
+ _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
+ _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
+ _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
+ float, int, long),
+ _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
+ float, int, long),
+ _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
+ _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str),
+ }
+
+
+# Map from field type to a function F, such that F(field_num, value)
+# gives the total byte size for a value of the given type. This
+# byte size includes tag information and any other additional space
+# associated with serializing "value".
+TYPE_TO_BYTE_SIZE_FN = {
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
+ _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
+ _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
+ _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
+ _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
+ _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
+ _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
+ _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
+ _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
+ _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
+ _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
+ _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
+ _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
+ _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
+ _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
+ _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
+ }
+
+
+# Maps from field types to encoder constructors.
+TYPE_TO_ENCODER = {
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder,
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder,
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder,
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder,
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder,
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder,
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder,
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder,
+ _FieldDescriptor.TYPE_STRING: encoder.StringEncoder,
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder,
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder,
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder,
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder,
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder,
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder,
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder,
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder,
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder,
+ }
+
+
+# Maps from field types to sizer constructors.
+TYPE_TO_SIZER = {
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer,
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer,
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer,
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer,
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer,
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer,
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer,
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer,
+ _FieldDescriptor.TYPE_STRING: encoder.StringSizer,
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer,
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer,
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer,
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer,
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer,
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer,
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer,
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer,
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer,
+ }
+
+
+# Maps from field type to a decoder constructor.
+TYPE_TO_DECODER = {
+ _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder,
+ _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder,
+ _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder,
+ _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder,
+ _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder,
+ _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder,
+ _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder,
+ _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder,
+ _FieldDescriptor.TYPE_STRING: decoder.StringDecoder,
+ _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder,
+ _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder,
+ _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder,
+ _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder,
+ _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder,
+ _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder,
+ _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder,
+ _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder,
+ _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder,
+ }
+
+# Maps from field type to expected wiretype.
+FIELD_TYPE_TO_WIRE_TYPE = {
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_STRING:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
+ _FieldDescriptor.TYPE_MESSAGE:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_BYTES:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
+ }
diff --git a/code/push/google/protobuf/internal/unknown_fields_test.py b/code/push/google/protobuf/internal/unknown_fields_test.py
new file mode 100644
index 0000000..84984b4
--- /dev/null
+++ b/code/push/google/protobuf/internal/unknown_fields_test.py
@@ -0,0 +1,170 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for preservation of unknown fields in the pure Python implementation."""
+
+__author__ = 'bohdank@google.com (Bohdan Koval)'
+
+import unittest
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import encoder
+from google.protobuf.internal import test_util
+from google.protobuf.internal import type_checkers
+
+
+class UnknownFieldsTest(unittest.TestCase):
+
+ def setUp(self):
+ self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ self.all_fields = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(self.all_fields)
+ self.all_fields_data = self.all_fields.SerializeToString()
+ self.empty_message = unittest_pb2.TestEmptyMessage()
+ self.empty_message.ParseFromString(self.all_fields_data)
+ self.unknown_fields = self.empty_message._unknown_fields
+
+ def GetField(self, name):
+ field_descriptor = self.descriptor.fields_by_name[name]
+ wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+ field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+ for tag_bytes, value in self.unknown_fields:
+ if tag_bytes == field_tag:
+ decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes]
+ result_dict = {}
+ decoder(value, 0, len(value), self.all_fields, result_dict)
+ return result_dict[field_descriptor]
+
+ def testVarint(self):
+ value = self.GetField('optional_int32')
+ self.assertEqual(self.all_fields.optional_int32, value)
+
+ def testFixed32(self):
+ value = self.GetField('optional_fixed32')
+ self.assertEqual(self.all_fields.optional_fixed32, value)
+
+ def testFixed64(self):
+ value = self.GetField('optional_fixed64')
+ self.assertEqual(self.all_fields.optional_fixed64, value)
+
+ def testLengthDelimited(self):
+ value = self.GetField('optional_string')
+ self.assertEqual(self.all_fields.optional_string, value)
+
+ def testGroup(self):
+ value = self.GetField('optionalgroup')
+ self.assertEqual(self.all_fields.optionalgroup, value)
+
+ def testSerialize(self):
+ data = self.empty_message.SerializeToString()
+
+ # Don't use assertEqual because we don't want to dump raw binary data to
+ # stdout.
+ self.assertTrue(data == self.all_fields_data)
+
+ def testCopyFrom(self):
+ message = unittest_pb2.TestEmptyMessage()
+ message.CopyFrom(self.empty_message)
+ self.assertEqual(self.unknown_fields, message._unknown_fields)
+
+ def testMergeFrom(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_int32 = 1
+ message.optional_uint32 = 2
+ source = unittest_pb2.TestEmptyMessage()
+ source.ParseFromString(message.SerializeToString())
+
+ message.ClearField('optional_int32')
+ message.optional_int64 = 3
+ message.optional_uint32 = 4
+ destination = unittest_pb2.TestEmptyMessage()
+ destination.ParseFromString(message.SerializeToString())
+ unknown_fields = destination._unknown_fields[:]
+
+ destination.MergeFrom(source)
+ self.assertEqual(unknown_fields + source._unknown_fields,
+ destination._unknown_fields)
+
+ def testClear(self):
+ self.empty_message.Clear()
+ self.assertEqual(0, len(self.empty_message._unknown_fields))
+
+ def testByteSize(self):
+ self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize())
+
+ def testUnknownExtensions(self):
+ message = unittest_pb2.TestEmptyMessageWithExtensions()
+ message.ParseFromString(self.all_fields_data)
+ self.assertEqual(self.empty_message._unknown_fields,
+ message._unknown_fields)
+
+ def testListFields(self):
+ # Make sure ListFields doesn't return unknown fields.
+ self.assertEqual(0, len(self.empty_message.ListFields()))
+
+ def testSerializeMessageSetWireFormatUnknownExtension(self):
+ # Create a message using the message set wire format with an unknown
+ # message.
+ raw = unittest_mset_pb2.RawMessageSet()
+
+ # Add an unknown extension.
+ item = raw.item.add()
+ item.type_id = 1545009
+ message1 = unittest_mset_pb2.TestMessageSetExtension1()
+ message1.i = 12345
+ item.message = message1.SerializeToString()
+
+ serialized = raw.SerializeToString()
+
+ # Parse message using the message set wire format.
+ proto = unittest_mset_pb2.TestMessageSet()
+ proto.MergeFromString(serialized)
+
+ # Verify that the unknown extension is serialized unchanged
+ reserialized = proto.SerializeToString()
+ new_raw = unittest_mset_pb2.RawMessageSet()
+ new_raw.MergeFromString(reserialized)
+ self.assertEqual(raw, new_raw)
+
+ def testEquals(self):
+ message = unittest_pb2.TestEmptyMessage()
+ message.ParseFromString(self.all_fields_data)
+ self.assertEqual(self.empty_message, message)
+
+ self.all_fields.ClearField('optional_string')
+ message.ParseFromString(self.all_fields.SerializeToString())
+ self.assertNotEqual(self.empty_message, message)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/internal/wire_format.py b/code/push/google/protobuf/internal/wire_format.py
new file mode 100644
index 0000000..ef73377
--- /dev/null
+++ b/code/push/google/protobuf/internal/wire_format.py
@@ -0,0 +1,268 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Constants and static functions to support protocol buffer wire format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import struct
+from push.google.protobuf import descriptor
+from push.google.protobuf import message
+
+
+TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag.
+TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7
+
+# These numbers identify the wire type of a protocol buffer value.
+# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded
+# tag-and-type to store one of these WIRETYPE_* constants.
+# These values must match WireType enum in google/protobuf/wire_format.h.
+WIRETYPE_VARINT = 0
+WIRETYPE_FIXED64 = 1
+WIRETYPE_LENGTH_DELIMITED = 2
+WIRETYPE_START_GROUP = 3
+WIRETYPE_END_GROUP = 4
+WIRETYPE_FIXED32 = 5
+_WIRETYPE_MAX = 5
+
+
+# Bounds for various integer types.
+INT32_MAX = int((1 << 31) - 1)
+INT32_MIN = int(-(1 << 31))
+UINT32_MAX = (1 << 32) - 1
+
+INT64_MAX = (1 << 63) - 1
+INT64_MIN = -(1 << 63)
+UINT64_MAX = (1 << 64) - 1
+
+# "struct" format strings that will encode/decode the specified formats.
+FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK)
+
+
+def ZigZagEncode(value):
+ """ZigZag Transform: Encodes signed integers so that they can be
+ effectively used with varint encoding. See wire_format.h for
+ more details.
+ """
+ if value >= 0:
+ return value << 1
+ return (value << 1) ^ (~0)
+
+
+def ZigZagDecode(value):
+ """Inverse of ZigZagEncode()."""
+ if not value & 0x1:
+ return value >> 1
+ return (value >> 1) ^ (~0)
+
+
+
+# The *ByteSize() functions below return the number of bytes required to
+# serialize "field number + type" information and then serialize the value.
+
+
+def Int32ByteSize(field_number, int32):
+ return Int64ByteSize(field_number, int32)
+
+
+def Int32ByteSizeNoTag(int32):
+ return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32)
+
+
+def Int64ByteSize(field_number, int64):
+ # Have to convert to uint before calling UInt64ByteSize().
+ return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
+
+
+def UInt32ByteSize(field_number, uint32):
+ return UInt64ByteSize(field_number, uint32)
+
+
+def UInt64ByteSize(field_number, uint64):
+ return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
+
+
+def SInt32ByteSize(field_number, int32):
+ return UInt32ByteSize(field_number, ZigZagEncode(int32))
+
+
+def SInt64ByteSize(field_number, int64):
+ return UInt64ByteSize(field_number, ZigZagEncode(int64))
+
+
+def Fixed32ByteSize(field_number, fixed32):
+ return TagByteSize(field_number) + 4
+
+
+def Fixed64ByteSize(field_number, fixed64):
+ return TagByteSize(field_number) + 8
+
+
+def SFixed32ByteSize(field_number, sfixed32):
+ return TagByteSize(field_number) + 4
+
+
+def SFixed64ByteSize(field_number, sfixed64):
+ return TagByteSize(field_number) + 8
+
+
+def FloatByteSize(field_number, flt):
+ return TagByteSize(field_number) + 4
+
+
+def DoubleByteSize(field_number, double):
+ return TagByteSize(field_number) + 8
+
+
+def BoolByteSize(field_number, b):
+ return TagByteSize(field_number) + 1
+
+
+def EnumByteSize(field_number, enum):
+ return UInt32ByteSize(field_number, enum)
+
+
+def StringByteSize(field_number, string):
+ return BytesByteSize(field_number, string.encode('utf-8'))
+
+
+def BytesByteSize(field_number, b):
+ return (TagByteSize(field_number)
+ + _VarUInt64ByteSizeNoTag(len(b))
+ + len(b))
+
+
+def GroupByteSize(field_number, message):
+ return (2 * TagByteSize(field_number) # START and END group.
+ + message.ByteSize())
+
+
+def MessageByteSize(field_number, message):
+ return (TagByteSize(field_number)
+ + _VarUInt64ByteSizeNoTag(message.ByteSize())
+ + message.ByteSize())
+
+
+def MessageSetItemByteSize(field_number, msg):
+ # First compute the sizes of the tags.
+ # There are 2 tags for the beginning and ending of the repeated group, that
+ # is field number 1, one with field number 2 (type_id) and one with field
+ # number 3 (message).
+ total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3))
+
+ # Add the number of bytes for type_id.
+ total_size += _VarUInt64ByteSizeNoTag(field_number)
+
+ message_size = msg.ByteSize()
+
+ # The number of bytes for encoding the length of the message.
+ total_size += _VarUInt64ByteSizeNoTag(message_size)
+
+ # The size of the message.
+ total_size += message_size
+ return total_size
+
+
+def TagByteSize(field_number):
+ """Returns the bytes required to serialize a tag with this field number."""
+ # Just pass in type 0, since the type won't affect the tag+type size.
+ return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0))
+
+
+# Private helper function for the *ByteSize() functions above.
+
+def _VarUInt64ByteSizeNoTag(uint64):
+ """Returns the number of bytes required to serialize a single varint
+ using boundary value comparisons. (unrolled loop optimization -WPierce)
+ uint64 must be unsigned.
+ """
+ if uint64 <= 0x7f: return 1
+ if uint64 <= 0x3fff: return 2
+ if uint64 <= 0x1fffff: return 3
+ if uint64 <= 0xfffffff: return 4
+ if uint64 <= 0x7ffffffff: return 5
+ if uint64 <= 0x3ffffffffff: return 6
+ if uint64 <= 0x1ffffffffffff: return 7
+ if uint64 <= 0xffffffffffffff: return 8
+ if uint64 <= 0x7fffffffffffffff: return 9
+ if uint64 > UINT64_MAX:
+ raise message.EncodeError('Value out of range: %d' % uint64)
+ return 10
+
+
+NON_PACKABLE_TYPES = (
+ descriptor.FieldDescriptor.TYPE_STRING,
+ descriptor.FieldDescriptor.TYPE_GROUP,
+ descriptor.FieldDescriptor.TYPE_MESSAGE,
+ descriptor.FieldDescriptor.TYPE_BYTES
+)
+
+
+def IsTypePackable(field_type):
+ """Return true iff packable = true is valid for fields of this type.
+
+ Args:
+ field_type: a FieldDescriptor::Type value.
+
+ Returns:
+ True iff fields of this type are packable.
+ """
+ return field_type not in NON_PACKABLE_TYPES
diff --git a/code/push/google/protobuf/internal/wire_format_test.py b/code/push/google/protobuf/internal/wire_format_test.py
new file mode 100644
index 0000000..7600778
--- /dev/null
+++ b/code/push/google/protobuf/internal/wire_format_test.py
@@ -0,0 +1,253 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for google.protobuf.internal.wire_format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import unittest
+from google.protobuf import message
+from google.protobuf.internal import wire_format
+
+
+class WireFormatTest(unittest.TestCase):
+
+ def testPackTag(self):
+ field_number = 0xabc
+ tag_type = 2
+ self.assertEqual((field_number << 3) | tag_type,
+ wire_format.PackTag(field_number, tag_type))
+ PackTag = wire_format.PackTag
+ # Number too high.
+ self.assertRaises(message.EncodeError, PackTag, field_number, 6)
+ # Number too low.
+ self.assertRaises(message.EncodeError, PackTag, field_number, -1)
+
+ def testUnpackTag(self):
+ # Test field numbers that will require various varint sizes.
+ for expected_field_number in (1, 15, 16, 2047, 2048):
+ for expected_wire_type in range(6): # Highest-numbered wiretype is 5.
+ field_number, wire_type = wire_format.UnpackTag(
+ wire_format.PackTag(expected_field_number, expected_wire_type))
+ self.assertEqual(expected_field_number, field_number)
+ self.assertEqual(expected_wire_type, wire_type)
+
+ self.assertRaises(TypeError, wire_format.UnpackTag, None)
+ self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
+ self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
+ self.assertRaises(TypeError, wire_format.UnpackTag, object())
+
+ def testZigZagEncode(self):
+ Z = wire_format.ZigZagEncode
+ self.assertEqual(0, Z(0))
+ self.assertEqual(1, Z(-1))
+ self.assertEqual(2, Z(1))
+ self.assertEqual(3, Z(-2))
+ self.assertEqual(4, Z(2))
+ self.assertEqual(0xfffffffe, Z(0x7fffffff))
+ self.assertEqual(0xffffffff, Z(-0x80000000))
+ self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
+ self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
+
+ self.assertRaises(TypeError, Z, None)
+ self.assertRaises(TypeError, Z, 'abcd')
+ self.assertRaises(TypeError, Z, 0.0)
+ self.assertRaises(TypeError, Z, object())
+
+ def testZigZagDecode(self):
+ Z = wire_format.ZigZagDecode
+ self.assertEqual(0, Z(0))
+ self.assertEqual(-1, Z(1))
+ self.assertEqual(1, Z(2))
+ self.assertEqual(-2, Z(3))
+ self.assertEqual(2, Z(4))
+ self.assertEqual(0x7fffffff, Z(0xfffffffe))
+ self.assertEqual(-0x80000000, Z(0xffffffff))
+ self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
+ self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
+
+ self.assertRaises(TypeError, Z, None)
+ self.assertRaises(TypeError, Z, 'abcd')
+ self.assertRaises(TypeError, Z, 0.0)
+ self.assertRaises(TypeError, Z, object())
+
+ def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
+ # Use field numbers that cause various byte sizes for the tag information.
+ for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
+ expected_size = expected_value_size + tag_bytes
+ actual_size = byte_size_fn(field_number, value)
+ self.assertEqual(expected_size, actual_size,
+ 'byte_size_fn: %s, field_number: %d, value: %r\n'
+ 'Expected: %d, Actual: %d'% (
+ byte_size_fn, field_number, value, expected_size, actual_size))
+
+ def testByteSizeFunctions(self):
+ # Test all numeric *ByteSize() functions.
+ NUMERIC_ARGS = [
+ # Int32ByteSize().
+ [wire_format.Int32ByteSize, 0, 1],
+ [wire_format.Int32ByteSize, 127, 1],
+ [wire_format.Int32ByteSize, 128, 2],
+ [wire_format.Int32ByteSize, -1, 10],
+ # Int64ByteSize().
+ [wire_format.Int64ByteSize, 0, 1],
+ [wire_format.Int64ByteSize, 127, 1],
+ [wire_format.Int64ByteSize, 128, 2],
+ [wire_format.Int64ByteSize, -1, 10],
+ # UInt32ByteSize().
+ [wire_format.UInt32ByteSize, 0, 1],
+ [wire_format.UInt32ByteSize, 127, 1],
+ [wire_format.UInt32ByteSize, 128, 2],
+ [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
+ # UInt64ByteSize().
+ [wire_format.UInt64ByteSize, 0, 1],
+ [wire_format.UInt64ByteSize, 127, 1],
+ [wire_format.UInt64ByteSize, 128, 2],
+ [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
+ # SInt32ByteSize().
+ [wire_format.SInt32ByteSize, 0, 1],
+ [wire_format.SInt32ByteSize, -1, 1],
+ [wire_format.SInt32ByteSize, 1, 1],
+ [wire_format.SInt32ByteSize, -63, 1],
+ [wire_format.SInt32ByteSize, 63, 1],
+ [wire_format.SInt32ByteSize, -64, 1],
+ [wire_format.SInt32ByteSize, 64, 2],
+ # SInt64ByteSize().
+ [wire_format.SInt64ByteSize, 0, 1],
+ [wire_format.SInt64ByteSize, -1, 1],
+ [wire_format.SInt64ByteSize, 1, 1],
+ [wire_format.SInt64ByteSize, -63, 1],
+ [wire_format.SInt64ByteSize, 63, 1],
+ [wire_format.SInt64ByteSize, -64, 1],
+ [wire_format.SInt64ByteSize, 64, 2],
+ # Fixed32ByteSize().
+ [wire_format.Fixed32ByteSize, 0, 4],
+ [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
+ # Fixed64ByteSize().
+ [wire_format.Fixed64ByteSize, 0, 8],
+ [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
+ # SFixed32ByteSize().
+ [wire_format.SFixed32ByteSize, 0, 4],
+ [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
+ [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
+ # SFixed64ByteSize().
+ [wire_format.SFixed64ByteSize, 0, 8],
+ [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
+ [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
+ # FloatByteSize().
+ [wire_format.FloatByteSize, 0.0, 4],
+ [wire_format.FloatByteSize, 1000000000.0, 4],
+ [wire_format.FloatByteSize, -1000000000.0, 4],
+ # DoubleByteSize().
+ [wire_format.DoubleByteSize, 0.0, 8],
+ [wire_format.DoubleByteSize, 1000000000.0, 8],
+ [wire_format.DoubleByteSize, -1000000000.0, 8],
+ # BoolByteSize().
+ [wire_format.BoolByteSize, False, 1],
+ [wire_format.BoolByteSize, True, 1],
+ # EnumByteSize().
+ [wire_format.EnumByteSize, 0, 1],
+ [wire_format.EnumByteSize, 127, 1],
+ [wire_format.EnumByteSize, 128, 2],
+ [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
+ ]
+ for args in NUMERIC_ARGS:
+ self.NumericByteSizeTestHelper(*args)
+
+ # Test strings and bytes.
+ for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
+ # 1 byte for tag, 1 byte for length, 3 bytes for contents.
+ self.assertEqual(5, byte_size_fn(10, 'abc'))
+ # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
+ self.assertEqual(6, byte_size_fn(16, 'abc'))
+ # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
+ self.assertEqual(132, byte_size_fn(16, 'a' * 128))
+
+ # Test UTF-8 string byte size calculation.
+ # 1 byte for tag, 1 byte for length, 8 bytes for content.
+ self.assertEqual(10, wire_format.StringByteSize(
+ 5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8')))
+
+ class MockMessage(object):
+ def __init__(self, byte_size):
+ self.byte_size = byte_size
+ def ByteSize(self):
+ return self.byte_size
+
+ message_byte_size = 10
+ mock_message = MockMessage(byte_size=message_byte_size)
+ # Test groups.
+ # (2 * 1) bytes for begin and end tags, plus message_byte_size.
+ self.assertEqual(2 + message_byte_size,
+ wire_format.GroupByteSize(1, mock_message))
+ # (2 * 2) bytes for begin and end tags, plus message_byte_size.
+ self.assertEqual(4 + message_byte_size,
+ wire_format.GroupByteSize(16, mock_message))
+
+ # Test messages.
+ # 1 byte for tag, plus 1 byte for length, plus contents.
+ self.assertEqual(2 + mock_message.byte_size,
+ wire_format.MessageByteSize(1, mock_message))
+ # 2 bytes for tag, plus 1 byte for length, plus contents.
+ self.assertEqual(3 + mock_message.byte_size,
+ wire_format.MessageByteSize(16, mock_message))
+ # 2 bytes for tag, plus 2 bytes for length, plus contents.
+ mock_message.byte_size = 128
+ self.assertEqual(4 + mock_message.byte_size,
+ wire_format.MessageByteSize(16, mock_message))
+
+
+ # Test message set item byte size.
+ # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
+ # plus contents.
+ mock_message.byte_size = 10
+ self.assertEqual(mock_message.byte_size + 6,
+ wire_format.MessageSetItemByteSize(1, mock_message))
+
+ # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
+ # plus contents.
+ mock_message.byte_size = 128
+ self.assertEqual(mock_message.byte_size + 7,
+ wire_format.MessageSetItemByteSize(1, mock_message))
+
+ # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
+ # plus contents.
+ self.assertEqual(mock_message.byte_size + 8,
+ wire_format.MessageSetItemByteSize(128, mock_message))
+
+ # Too-long varint.
+ self.assertRaises(message.EncodeError,
+ wire_format.UInt64ByteSize, 1, 1 << 128)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/code/push/google/protobuf/message.py b/code/push/google/protobuf/message.py
new file mode 100644
index 0000000..6ec2f8b
--- /dev/null
+++ b/code/push/google/protobuf/message.py
@@ -0,0 +1,280 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(robinson): We should just make these methods all "pure-virtual" and move
+# all implementation out, into reflection.py for now.
+
+
+"""Contains an abstract base class for protocol messages."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class Error(Exception): pass
+class DecodeError(Error): pass
+class EncodeError(Error): pass
+
+
+class Message(object):
+
+ """Abstract base class for protocol messages.
+
+ Protocol message classes are almost always generated by the protocol
+ compiler. These generated types subclass Message and implement the methods
+ shown below.
+
+ TODO(robinson): Link to an HTML document here.
+
+ TODO(robinson): Document that instances of this class will also
+ have an Extensions attribute with __getitem__ and __setitem__.
+ Again, not sure how to best convey this.
+
+ TODO(robinson): Document that the class must also have a static
+ RegisterExtension(extension_field) method.
+ Not sure how to best express at this point.
+ """
+
+ # TODO(robinson): Document these fields and methods.
+
+ __slots__ = []
+
+ DESCRIPTOR = None
+
+ def __deepcopy__(self, memo=None):
+ clone = type(self)()
+ clone.MergeFrom(self)
+ return clone
+
+ def __eq__(self, other_msg):
+ """Recursively compares two messages by value and structure."""
+ raise NotImplementedError
+
+ def __ne__(self, other_msg):
+ # Can't just say self != other_msg, since that would infinitely recurse. :)
+ return not self == other_msg
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __str__(self):
+ """Outputs a human-readable representation of the message."""
+ raise NotImplementedError
+
+ def __unicode__(self):
+ """Outputs a human-readable representation of the message."""
+ raise NotImplementedError
+
+ def MergeFrom(self, other_msg):
+ """Merges the contents of the specified message into current message.
+
+ This method merges the contents of the specified message into the current
+ message. Singular fields that are set in the specified message overwrite
+ the corresponding fields in the current message. Repeated fields are
+ appended. Singular sub-messages and groups are recursively merged.
+
+ Args:
+ other_msg: Message to merge into the current message.
+ """
+ raise NotImplementedError
+
+ def CopyFrom(self, other_msg):
+ """Copies the content of the specified message into the current message.
+
+ The method clears the current message and then merges the specified
+ message using MergeFrom.
+
+ Args:
+ other_msg: Message to copy into the current one.
+ """
+ if self is other_msg:
+ return
+ self.Clear()
+ self.MergeFrom(other_msg)
+
+ def Clear(self):
+ """Clears all data that was set in the message."""
+ raise NotImplementedError
+
+ def SetInParent(self):
+ """Mark this as present in the parent.
+
+ This normally happens automatically when you assign a field of a
+ sub-message, but sometimes you want to make the sub-message
+ present while keeping it empty. If you find yourself using this,
+ you may want to reconsider your design."""
+ raise NotImplementedError
+
+ def IsInitialized(self):
+ """Checks if the message is initialized.
+
+ Returns:
+ The method returns True if the message is initialized (i.e. all of its
+ required fields are set).
+ """
+ raise NotImplementedError
+
+ # TODO(robinson): MergeFromString() should probably return None and be
+ # implemented in terms of a helper that returns the # of bytes read. Our
+ # deserialization routines would use the helper when recursively
+ # deserializing, but the end user would almost always just want the no-return
+ # MergeFromString().
+
+ def MergeFromString(self, serialized):
+ """Merges serialized protocol buffer data into this message.
+
+ When we find a field in |serialized| that is already present
+ in this message:
+ - If it's a "repeated" field, we append to the end of our list.
+ - Else, if it's a scalar, we overwrite our field.
+ - Else, (it's a nonrepeated composite), we recursively merge
+ into the existing composite.
+
+ TODO(robinson): Document handling of unknown fields.
+
+ Args:
+ serialized: Any object that allows us to call buffer(serialized)
+ to access a string of bytes using the buffer interface.
+
+ TODO(robinson): When we switch to a helper, this will return None.
+
+ Returns:
+ The number of bytes read from |serialized|.
+ For non-group messages, this will always be len(serialized),
+ but for messages which are actually groups, this will
+ generally be less than len(serialized), since we must
+ stop when we reach an END_GROUP tag. Note that if
+ we *do* stop because of an END_GROUP tag, the number
+ of bytes returned does not include the bytes
+ for the END_GROUP tag information.
+ """
+ raise NotImplementedError
+
+ def ParseFromString(self, serialized):
+ """Like MergeFromString(), except we clear the object first."""
+ self.Clear()
+ self.MergeFromString(serialized)
+
+ def SerializeToString(self):
+ """Serializes the protocol message to a binary string.
+
+ Returns:
+ A binary string representation of the message if all of the required
+ fields in the message are set (i.e. the message is initialized).
+
+ Raises:
+ message.EncodeError if the message isn't initialized.
+ """
+ raise NotImplementedError
+
+ def SerializePartialToString(self):
+ """Serializes the protocol message to a binary string.
+
+ This method is similar to SerializeToString but doesn't check if the
+ message is initialized.
+
+ Returns:
+ A string representation of the partial message.
+ """
+ raise NotImplementedError
+
+ # TODO(robinson): Decide whether we like these better
+ # than auto-generated has_foo() and clear_foo() methods
+ # on the instances themselves. This way is less consistent
+ # with C++, but it makes reflection-type access easier and
+ # reduces the number of magically autogenerated things.
+ #
+ # TODO(robinson): Be sure to document (and test) exactly
+ # which field names are accepted here. Are we case-sensitive?
+ # What do we do with fields that share names with Python keywords
+ # like 'lambda' and 'yield'?
+ #
+ # nnorwitz says:
+ # """
+ # Typically (in python), an underscore is appended to names that are
+ # keywords. So they would become lambda_ or yield_.
+ # """
+ def ListFields(self):
+ """Returns a list of (FieldDescriptor, value) tuples for all
+ fields in the message which are not empty. A singular field is non-empty
+ if HasField() would return true, and a repeated field is non-empty if
+ it contains at least one element. The fields are ordered by field
+ number"""
+ raise NotImplementedError
+
+ def HasField(self, field_name):
+ """Checks if a certain field is set for the message. Note if the
+ field_name is not defined in the message descriptor, ValueError will be
+ raised."""
+ raise NotImplementedError
+
+ def ClearField(self, field_name):
+ raise NotImplementedError
+
+ def HasExtension(self, extension_handle):
+ raise NotImplementedError
+
+ def ClearExtension(self, extension_handle):
+ raise NotImplementedError
+
+ def ByteSize(self):
+ """Returns the serialized size of this message.
+ Recursively calls ByteSize() on all contained messages.
+ """
+ raise NotImplementedError
+
+ def _SetListener(self, message_listener):
+ """Internal method used by the protocol message implementation.
+ Clients should not call this directly.
+
+ Sets a listener that this message will call on certain state transitions.
+
+ The purpose of this method is to register back-edges from children to
+ parents at runtime, for the purpose of setting "has" bits and
+ byte-size-dirty bits in the parent and ancestor objects whenever a child or
+ descendant object is modified.
+
+ If the client wants to disconnect this Message from the object tree, she
+ explicitly sets callback to None.
+
+ If message_listener is None, unregisters any existing listener. Otherwise,
+ message_listener must implement the MessageListener interface in
+ internal/message_listener.py, and we discard any listener registered
+ via a previous _SetListener() call.
+ """
+ raise NotImplementedError
+
+ def __getstate__(self):
+ """Support the pickle protocol."""
+ return dict(serialized=self.SerializePartialToString())
+
+ def __setstate__(self, state):
+ """Support the pickle protocol."""
+ self.__init__()
+ self.ParseFromString(state['serialized'])
diff --git a/code/push/google/protobuf/message_factory.py b/code/push/google/protobuf/message_factory.py
new file mode 100644
index 0000000..36e2fef
--- /dev/null
+++ b/code/push/google/protobuf/message_factory.py
@@ -0,0 +1,113 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides a factory class for generating dynamic messages."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message
+from google.protobuf import reflection
+
+
+class MessageFactory(object):
+ """Factory for creating Proto2 messages from descriptors in a pool."""
+
+ def __init__(self):
+ """Initializes a new factory."""
+ self._classes = {}
+
+ def GetPrototype(self, descriptor):
+ """Builds a proto2 message class based on the passed in descriptor.
+
+ Passing a descriptor with a fully qualified name matching a previous
+ invocation will cause the same class to be returned.
+
+ Args:
+ descriptor: The descriptor to build from.
+
+ Returns:
+ A class describing the passed in descriptor.
+ """
+
+ if descriptor.full_name not in self._classes:
+ result_class = reflection.GeneratedProtocolMessageType(
+ descriptor.name.encode('ascii', 'ignore'),
+ (message.Message,),
+ {'DESCRIPTOR': descriptor})
+ self._classes[descriptor.full_name] = result_class
+ for field in descriptor.fields:
+ if field.message_type:
+ self.GetPrototype(field.message_type)
+ return self._classes[descriptor.full_name]
+
+
+_DB = descriptor_database.DescriptorDatabase()
+_POOL = descriptor_pool.DescriptorPool(_DB)
+_FACTORY = MessageFactory()
+
+
+def GetMessages(file_protos):
+ """Builds a dictionary of all the messages available in a set of files.
+
+ Args:
+ file_protos: A sequence of file protos to build messages out of.
+
+ Returns:
+ A dictionary containing all the message types in the files mapping the
+ fully qualified name to a Message subclass for the descriptor.
+ """
+
+ result = {}
+ for file_proto in file_protos:
+ _DB.Add(file_proto)
+ for file_proto in file_protos:
+ for desc in _GetAllDescriptors(file_proto.message_type, file_proto.package):
+ result[desc.full_name] = _FACTORY.GetPrototype(desc)
+ return result
+
+
+def _GetAllDescriptors(desc_protos, package):
+ """Gets all levels of nested message types as a flattened list of descriptors.
+
+ Args:
+ desc_protos: The descriptor protos to process.
+ package: The package where the protos are defined.
+
+ Yields:
+ Each message descriptor for each nested type.
+ """
+
+ for desc_proto in desc_protos:
+ name = '.'.join((package, desc_proto.name))
+ yield _POOL.FindMessageTypeByName(name)
+ for nested_desc in _GetAllDescriptors(desc_proto.nested_type, name):
+ yield nested_desc
diff --git a/code/push/google/protobuf/pyext/python-proto2.cc b/code/push/google/protobuf/pyext/python-proto2.cc
new file mode 100644
index 0000000..eebb752
--- /dev/null
+++ b/code/push/google/protobuf/pyext/python-proto2.cc
@@ -0,0 +1,1717 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#include
+#include