reproto 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .git/HEAD +1 -0
- .git/config +12 -0
- .git/description +1 -0
- .git/hooks/applypatch-msg.sample +15 -0
- .git/hooks/commit-msg.sample +24 -0
- .git/hooks/fsmonitor-watchman.sample +174 -0
- .git/hooks/post-update.sample +8 -0
- .git/hooks/pre-applypatch.sample +14 -0
- .git/hooks/pre-commit.sample +49 -0
- .git/hooks/pre-merge-commit.sample +13 -0
- .git/hooks/pre-push.sample +53 -0
- .git/hooks/pre-rebase.sample +169 -0
- .git/hooks/pre-receive.sample +24 -0
- .git/hooks/prepare-commit-msg.sample +42 -0
- .git/hooks/push-to-checkout.sample +78 -0
- .git/hooks/sendemail-validate.sample +77 -0
- .git/hooks/update.sample +128 -0
- .git/index +0 -0
- .git/info/exclude +6 -0
- .git/logs/HEAD +1 -0
- .git/logs/refs/heads/iyue +1 -0
- .git/logs/refs/remotes/origin/HEAD +1 -0
- .git/objects/pack/pack-55d9855fa45cb686f64bef472f9a7940ef78b8d6.idx +0 -0
- .git/objects/pack/pack-55d9855fa45cb686f64bef472f9a7940ef78b8d6.pack +0 -0
- .git/objects/pack/pack-55d9855fa45cb686f64bef472f9a7940ef78b8d6.rev +0 -0
- .git/packed-refs +2 -0
- .git/refs/heads/iyue +1 -0
- .git/refs/remotes/origin/HEAD +1 -0
- .gitignore +142 -0
- .python-version +1 -0
- ARCHITECTURE.md +266 -0
- README.md +231 -0
- main.py +172 -0
- pyproject.toml +36 -0
- {reproto-0.0.3.dist-info → reproto-0.0.4.dist-info}/METADATA +1 -1
- reproto-0.0.4.dist-info/RECORD +53 -0
- requirements.txt +3 -0
- reproto-0.0.3.dist-info/RECORD +0 -18
- {reproto-0.0.3.dist-info → reproto-0.0.4.dist-info}/WHEEL +0 -0
- {reproto-0.0.3.dist-info → reproto-0.0.4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# An example hook script to validate a patch (and/or patch series) before
|
4
|
+
# sending it via email.
|
5
|
+
#
|
6
|
+
# The hook should exit with non-zero status after issuing an appropriate
|
7
|
+
# message if it wants to prevent the email(s) from being sent.
|
8
|
+
#
|
9
|
+
# To enable this hook, rename this file to "sendemail-validate".
|
10
|
+
#
|
11
|
+
# By default, it will only check that the patch(es) can be applied on top of
|
12
|
+
# the default upstream branch without conflicts in a secondary worktree. After
|
13
|
+
# validation (successful or not) of the last patch of a series, the worktree
|
14
|
+
# will be deleted.
|
15
|
+
#
|
16
|
+
# The following config variables can be set to change the default remote and
|
17
|
+
# remote ref that are used to apply the patches against:
|
18
|
+
#
|
19
|
+
# sendemail.validateRemote (default: origin)
|
20
|
+
# sendemail.validateRemoteRef (default: HEAD)
|
21
|
+
#
|
22
|
+
# Replace the TODO placeholders with appropriate checks according to your
|
23
|
+
# needs.
|
24
|
+
|
25
|
+
validate_cover_letter () {
|
26
|
+
file="$1"
|
27
|
+
# TODO: Replace with appropriate checks (e.g. spell checking).
|
28
|
+
true
|
29
|
+
}
|
30
|
+
|
31
|
+
validate_patch () {
|
32
|
+
file="$1"
|
33
|
+
# Ensure that the patch applies without conflicts.
|
34
|
+
git am -3 "$file" || return
|
35
|
+
# TODO: Replace with appropriate checks for this patch
|
36
|
+
# (e.g. checkpatch.pl).
|
37
|
+
true
|
38
|
+
}
|
39
|
+
|
40
|
+
validate_series () {
|
41
|
+
# TODO: Replace with appropriate checks for the whole series
|
42
|
+
# (e.g. quick build, coding style checks, etc.).
|
43
|
+
true
|
44
|
+
}
|
45
|
+
|
46
|
+
# main -------------------------------------------------------------------------
|
47
|
+
|
48
|
+
if test "$GIT_SENDEMAIL_FILE_COUNTER" = 1
|
49
|
+
then
|
50
|
+
remote=$(git config --default origin --get sendemail.validateRemote) &&
|
51
|
+
ref=$(git config --default HEAD --get sendemail.validateRemoteRef) &&
|
52
|
+
worktree=$(mktemp --tmpdir -d sendemail-validate.XXXXXXX) &&
|
53
|
+
git worktree add -fd --checkout "$worktree" "refs/remotes/$remote/$ref" &&
|
54
|
+
git config --replace-all sendemail.validateWorktree "$worktree"
|
55
|
+
else
|
56
|
+
worktree=$(git config --get sendemail.validateWorktree)
|
57
|
+
fi || {
|
58
|
+
echo "sendemail-validate: error: failed to prepare worktree" >&2
|
59
|
+
exit 1
|
60
|
+
}
|
61
|
+
|
62
|
+
unset GIT_DIR GIT_WORK_TREE
|
63
|
+
cd "$worktree" &&
|
64
|
+
|
65
|
+
if grep -q "^diff --git " "$1"
|
66
|
+
then
|
67
|
+
validate_patch "$1"
|
68
|
+
else
|
69
|
+
validate_cover_letter "$1"
|
70
|
+
fi &&
|
71
|
+
|
72
|
+
if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL"
|
73
|
+
then
|
74
|
+
git config --unset-all sendemail.validateWorktree &&
|
75
|
+
trap 'git worktree remove -ff "$worktree"' EXIT &&
|
76
|
+
validate_series
|
77
|
+
fi
|
.git/hooks/update.sample
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# An example hook script to block unannotated tags from entering.
|
4
|
+
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
5
|
+
#
|
6
|
+
# To enable this hook, rename this file to "update".
|
7
|
+
#
|
8
|
+
# Config
|
9
|
+
# ------
|
10
|
+
# hooks.allowunannotated
|
11
|
+
# This boolean sets whether unannotated tags will be allowed into the
|
12
|
+
# repository. By default they won't be.
|
13
|
+
# hooks.allowdeletetag
|
14
|
+
# This boolean sets whether deleting tags will be allowed in the
|
15
|
+
# repository. By default they won't be.
|
16
|
+
# hooks.allowmodifytag
|
17
|
+
# This boolean sets whether a tag may be modified after creation. By default
|
18
|
+
# it won't be.
|
19
|
+
# hooks.allowdeletebranch
|
20
|
+
# This boolean sets whether deleting branches will be allowed in the
|
21
|
+
# repository. By default they won't be.
|
22
|
+
# hooks.denycreatebranch
|
23
|
+
# This boolean sets whether remotely creating branches will be denied
|
24
|
+
# in the repository. By default this is allowed.
|
25
|
+
#
|
26
|
+
|
27
|
+
# --- Command line
|
28
|
+
refname="$1"
|
29
|
+
oldrev="$2"
|
30
|
+
newrev="$3"
|
31
|
+
|
32
|
+
# --- Safety check
|
33
|
+
if [ -z "$GIT_DIR" ]; then
|
34
|
+
echo "Don't run this script from the command line." >&2
|
35
|
+
echo " (if you want, you could supply GIT_DIR then run" >&2
|
36
|
+
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
37
|
+
exit 1
|
38
|
+
fi
|
39
|
+
|
40
|
+
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
41
|
+
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
42
|
+
exit 1
|
43
|
+
fi
|
44
|
+
|
45
|
+
# --- Config
|
46
|
+
allowunannotated=$(git config --type=bool hooks.allowunannotated)
|
47
|
+
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
|
48
|
+
denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
|
49
|
+
allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
|
50
|
+
allowmodifytag=$(git config --type=bool hooks.allowmodifytag)
|
51
|
+
|
52
|
+
# check for no description
|
53
|
+
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
54
|
+
case "$projectdesc" in
|
55
|
+
"Unnamed repository"* | "")
|
56
|
+
echo "*** Project description file hasn't been set" >&2
|
57
|
+
exit 1
|
58
|
+
;;
|
59
|
+
esac
|
60
|
+
|
61
|
+
# --- Check types
|
62
|
+
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
63
|
+
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
|
64
|
+
if [ "$newrev" = "$zero" ]; then
|
65
|
+
newrev_type=delete
|
66
|
+
else
|
67
|
+
newrev_type=$(git cat-file -t $newrev)
|
68
|
+
fi
|
69
|
+
|
70
|
+
case "$refname","$newrev_type" in
|
71
|
+
refs/tags/*,commit)
|
72
|
+
# un-annotated tag
|
73
|
+
short_refname=${refname##refs/tags/}
|
74
|
+
if [ "$allowunannotated" != "true" ]; then
|
75
|
+
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
76
|
+
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
77
|
+
exit 1
|
78
|
+
fi
|
79
|
+
;;
|
80
|
+
refs/tags/*,delete)
|
81
|
+
# delete tag
|
82
|
+
if [ "$allowdeletetag" != "true" ]; then
|
83
|
+
echo "*** Deleting a tag is not allowed in this repository" >&2
|
84
|
+
exit 1
|
85
|
+
fi
|
86
|
+
;;
|
87
|
+
refs/tags/*,tag)
|
88
|
+
# annotated tag
|
89
|
+
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
90
|
+
then
|
91
|
+
echo "*** Tag '$refname' already exists." >&2
|
92
|
+
echo "*** Modifying a tag is not allowed in this repository." >&2
|
93
|
+
exit 1
|
94
|
+
fi
|
95
|
+
;;
|
96
|
+
refs/heads/*,commit)
|
97
|
+
# branch
|
98
|
+
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
99
|
+
echo "*** Creating a branch is not allowed in this repository" >&2
|
100
|
+
exit 1
|
101
|
+
fi
|
102
|
+
;;
|
103
|
+
refs/heads/*,delete)
|
104
|
+
# delete branch
|
105
|
+
if [ "$allowdeletebranch" != "true" ]; then
|
106
|
+
echo "*** Deleting a branch is not allowed in this repository" >&2
|
107
|
+
exit 1
|
108
|
+
fi
|
109
|
+
;;
|
110
|
+
refs/remotes/*,commit)
|
111
|
+
# tracking branch
|
112
|
+
;;
|
113
|
+
refs/remotes/*,delete)
|
114
|
+
# delete tracking branch
|
115
|
+
if [ "$allowdeletebranch" != "true" ]; then
|
116
|
+
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
117
|
+
exit 1
|
118
|
+
fi
|
119
|
+
;;
|
120
|
+
*)
|
121
|
+
# Anything else (is there anything else?)
|
122
|
+
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
123
|
+
exit 1
|
124
|
+
;;
|
125
|
+
esac
|
126
|
+
|
127
|
+
# --- Finished
|
128
|
+
exit 0
|
.git/index
ADDED
Binary file
|
.git/info/exclude
ADDED
.git/logs/HEAD
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0000000000000000000000000000000000000000 514d3a743bced9f5c012a21032b49b81daec78ff iyue <ys1231@126.com> 1750903749 +0800 clone: from github.com:ys1231/reproto.git
|
@@ -0,0 +1 @@
|
|
1
|
+
0000000000000000000000000000000000000000 514d3a743bced9f5c012a21032b49b81daec78ff iyue <ys1231@126.com> 1750903749 +0800 clone: from github.com:ys1231/reproto.git
|
@@ -0,0 +1 @@
|
|
1
|
+
0000000000000000000000000000000000000000 514d3a743bced9f5c012a21032b49b81daec78ff iyue <ys1231@126.com> 1750903749 +0800 clone: from github.com:ys1231/reproto.git
|
Binary file
|
Binary file
|
Binary file
|
.git/packed-refs
ADDED
.git/refs/heads/iyue
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
514d3a743bced9f5c012a21032b49b81daec78ff
|
@@ -0,0 +1 @@
|
|
1
|
+
ref: refs/remotes/origin/iyue
|
.gitignore
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
2
|
+
__pycache__/
|
3
|
+
*.py[cod]
|
4
|
+
*$py.class
|
5
|
+
|
6
|
+
# C extensions
|
7
|
+
*.so
|
8
|
+
|
9
|
+
# Distribution / packaging
|
10
|
+
.Python
|
11
|
+
build/
|
12
|
+
develop-eggs/
|
13
|
+
dist/
|
14
|
+
downloads/
|
15
|
+
eggs/
|
16
|
+
.eggs/
|
17
|
+
lib/
|
18
|
+
lib64/
|
19
|
+
parts/
|
20
|
+
sdist/
|
21
|
+
var/
|
22
|
+
wheels/
|
23
|
+
share/python-wheels/
|
24
|
+
*.egg-info/
|
25
|
+
.installed.cfg
|
26
|
+
*.egg
|
27
|
+
MANIFEST
|
28
|
+
|
29
|
+
# PyInstaller
|
30
|
+
# Usually these files are written by a python script from a template
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32
|
+
*.manifest
|
33
|
+
*.spec
|
34
|
+
|
35
|
+
# Installer logs
|
36
|
+
pip-log.txt
|
37
|
+
pip-delete-this-directory.txt
|
38
|
+
|
39
|
+
# Unit test / coverage reports
|
40
|
+
htmlcov/
|
41
|
+
.tox/
|
42
|
+
.nox/
|
43
|
+
.coverage
|
44
|
+
.coverage.*
|
45
|
+
.cache
|
46
|
+
nosetests.xml
|
47
|
+
coverage.xml
|
48
|
+
*.cover
|
49
|
+
*.py,cover
|
50
|
+
.hypothesis/
|
51
|
+
.pytest_cache/
|
52
|
+
cover/
|
53
|
+
|
54
|
+
# Translations
|
55
|
+
*.mo
|
56
|
+
*.pot
|
57
|
+
|
58
|
+
# Django stuff:
|
59
|
+
*.log
|
60
|
+
local_settings.py
|
61
|
+
db.sqlite3
|
62
|
+
db.sqlite3-journal
|
63
|
+
|
64
|
+
# Flask stuff:
|
65
|
+
instance/
|
66
|
+
.webassets-cache
|
67
|
+
|
68
|
+
# Scrapy stuff:
|
69
|
+
.scrapy
|
70
|
+
|
71
|
+
# Sphinx documentation
|
72
|
+
docs/_build/
|
73
|
+
|
74
|
+
# PyBuilder
|
75
|
+
.pybuilder/
|
76
|
+
target/
|
77
|
+
|
78
|
+
# Jupyter Notebook
|
79
|
+
.ipynb_checkpoints
|
80
|
+
|
81
|
+
# IPython
|
82
|
+
profile_default/
|
83
|
+
ipython_config.py
|
84
|
+
|
85
|
+
# pyenv
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
88
|
+
# .python-version
|
89
|
+
|
90
|
+
# pipenv
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94
|
+
# install all needed dependencies.
|
95
|
+
#Pipfile.lock
|
96
|
+
|
97
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
98
|
+
__pypackages__/
|
99
|
+
|
100
|
+
# Celery stuff
|
101
|
+
celerybeat-schedule
|
102
|
+
celerybeat.pid
|
103
|
+
|
104
|
+
# SageMath parsed files
|
105
|
+
*.sage.py
|
106
|
+
|
107
|
+
# Environments
|
108
|
+
.env
|
109
|
+
.venv
|
110
|
+
env/
|
111
|
+
venv/
|
112
|
+
ENV/
|
113
|
+
env.bak/
|
114
|
+
venv.bak/
|
115
|
+
|
116
|
+
# Spyder project settings
|
117
|
+
.spyderproject
|
118
|
+
.spyproject
|
119
|
+
|
120
|
+
# Rope project settings
|
121
|
+
.ropeproject
|
122
|
+
|
123
|
+
# mkdocs documentation
|
124
|
+
/site
|
125
|
+
|
126
|
+
# mypy
|
127
|
+
.mypy_cache/
|
128
|
+
.dmypy.json
|
129
|
+
dmypy.json
|
130
|
+
|
131
|
+
# Pyre type checker
|
132
|
+
.pyre/
|
133
|
+
|
134
|
+
# pytype static type analyzer
|
135
|
+
.pytype/
|
136
|
+
|
137
|
+
# Cython debug symbols
|
138
|
+
cython_debug/
|
139
|
+
.vscode
|
140
|
+
.idea
|
141
|
+
poetry.lock
|
142
|
+
uv.lock
|
.python-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.13.0
|
ARCHITECTURE.md
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
# Protobuf Reconstructor 项目架构
|
2
|
+
|
3
|
+
## 🏗️ 总体架构
|
4
|
+
|
5
|
+
本项目采用模块化设计,将Protobuf逆向重构过程分解为多个独立的功能模块,确保代码的可维护性和可扩展性。
|
6
|
+
|
7
|
+
```
|
8
|
+
┌─────────────────────────────────────────────────────────────┐
|
9
|
+
│ main.py (入口点) │
|
10
|
+
├─────────────────────────────────────────────────────────────┤
|
11
|
+
│ core/reconstructor.py │
|
12
|
+
│ (主协调器) │
|
13
|
+
├─────────────────┬─────────────────┬─────────────────────────┤
|
14
|
+
│ parsing/ │ core/ │ generation/ │
|
15
|
+
│ java_parser.py │ info_decoder.py│ proto_generator.py │
|
16
|
+
│ (Java解析) │ (字节码解码) │ (Proto生成) │
|
17
|
+
├─────────────────┼─────────────────┼─────────────────────────┤
|
18
|
+
│ models/message_definition.py │
|
19
|
+
│ (数据模型) │
|
20
|
+
├─────────────────────────────────────────────────────────────┤
|
21
|
+
│ utils/ (工具模块) │
|
22
|
+
│ logger.py + file_utils.py │
|
23
|
+
└─────────────────────────────────────────────────────────────┘
|
24
|
+
```
|
25
|
+
|
26
|
+
## 📦 模块详解
|
27
|
+
|
28
|
+
### 1. 入口层 (Entry Layer)
|
29
|
+
|
30
|
+
#### `main.py`
|
31
|
+
- **职责**: 命令行接口,参数解析,程序入口
|
32
|
+
- **功能**:
|
33
|
+
- 解析命令行参数
|
34
|
+
- 初始化日志系统
|
35
|
+
- 创建并启动重构器
|
36
|
+
- 错误处理和用户反馈
|
37
|
+
|
38
|
+
### 2. 核心层 (Core Layer)
|
39
|
+
|
40
|
+
#### `core/reconstructor.py` - 主协调器
|
41
|
+
- **职责**: 整个重构流程的协调和管理
|
42
|
+
- **核心功能**:
|
43
|
+
- 类队列管理 (避免重复处理)
|
44
|
+
- 依赖发现和递归处理
|
45
|
+
- 模块间的协调调用
|
46
|
+
- 结果汇总和文件生成
|
47
|
+
- **设计模式**: 协调者模式 (Coordinator Pattern)
|
48
|
+
|
49
|
+
#### `core/info_decoder.py` - 字节码解码器
|
50
|
+
- **职责**: Google Protobuf Lite字节码的逆向解析
|
51
|
+
- **核心技术**:
|
52
|
+
- `newMessageInfo`字节码解码
|
53
|
+
- 字节码到Protobuf类型映射
|
54
|
+
- oneof字段识别 (通过`<`字符检测)
|
55
|
+
- 智能类型推断算法
|
56
|
+
- **技术突破**: 首次成功逆向Protobuf Lite字节码格式
|
57
|
+
|
58
|
+
### 3. 解析层 (Parsing Layer)
|
59
|
+
|
60
|
+
#### `parsing/java_parser.py` - Java源码解析器
|
61
|
+
- **职责**: 从Java源码中提取Protobuf相关信息
|
62
|
+
- **功能**:
|
63
|
+
- `newMessageInfo`调用提取
|
64
|
+
- 字节码字符串和对象数组解析
|
65
|
+
- 枚举值提取
|
66
|
+
- 依赖类型发现
|
67
|
+
|
68
|
+
#### `parsing/java_source_analyzer.py` - Java源码分析器
|
69
|
+
- **职责**: 直接从Java源码读取真实类型信息
|
70
|
+
- **功能**:
|
71
|
+
- 字段类型声明分析
|
72
|
+
- setter方法分析
|
73
|
+
- import语句解析
|
74
|
+
- 类型名智能匹配
|
75
|
+
|
76
|
+
### 4. 生成层 (Generation Layer)
|
77
|
+
|
78
|
+
#### `generation/proto_generator.py` - Proto文件生成器
|
79
|
+
- **职责**: 根据解析结果生成标准的.proto文件
|
80
|
+
- **功能**:
|
81
|
+
- 符合Google Style Guide的文件生成
|
82
|
+
- import语句智能管理
|
83
|
+
- 包结构自动推导
|
84
|
+
- Java选项自动设置
|
85
|
+
|
86
|
+
### 5. 数据模型层 (Model Layer)
|
87
|
+
|
88
|
+
#### `models/message_definition.py`
|
89
|
+
- **包含类型**:
|
90
|
+
- `MessageDefinition`: 消息类型定义
|
91
|
+
- `FieldDefinition`: 字段定义
|
92
|
+
- `OneofDefinition`: oneof字段定义
|
93
|
+
- `EnumDefinition`: 枚举类型定义
|
94
|
+
- `EnumValueDefinition`: 枚举值定义
|
95
|
+
|
96
|
+
### 6. 工具层 (Utility Layer)
|
97
|
+
|
98
|
+
#### `utils/logger.py`
|
99
|
+
- **职责**: 统一的日志管理
|
100
|
+
- **功能**: 基于loguru的日志系统
|
101
|
+
|
102
|
+
#### `utils/file_utils.py`
|
103
|
+
- **职责**: 文件操作工具
|
104
|
+
- **功能**: 文件读写、路径处理、目录创建
|
105
|
+
|
106
|
+
## 🔄 数据流向
|
107
|
+
|
108
|
+
```
|
109
|
+
1. Java源码输入
|
110
|
+
↓
|
111
|
+
2. JavaParser 提取字节码信息
|
112
|
+
↓
|
113
|
+
3. InfoDecoder 解码字节码 → MessageDefinition/EnumDefinition
|
114
|
+
↓
|
115
|
+
4. Reconstructor 发现依赖 → 递归处理
|
116
|
+
↓
|
117
|
+
5. ProtoGenerator 生成.proto文件
|
118
|
+
↓
|
119
|
+
6. 文件输出
|
120
|
+
```
|
121
|
+
|
122
|
+
## 🧠 核心算法
|
123
|
+
|
124
|
+
### 1. 字节码解码算法
|
125
|
+
```python
|
126
|
+
# 字节码格式: [字段标签, 字段类型] 对
|
127
|
+
# 特殊字符 '<' (ord=60) 标识oneof字段
|
128
|
+
def decode_message_info(info_string, objects):
|
129
|
+
bytes_data = decode_unicode_escapes(info_string)
|
130
|
+
for i in range(10, len(bytes_data)-1, 2): # 跳过元数据
|
131
|
+
field_tag = bytes_data[i]
|
132
|
+
field_type = type_mapping[bytes_data[i+1]]
|
133
|
+
# 处理字段...
|
134
|
+
```
|
135
|
+
|
136
|
+
### 2. 依赖发现算法
|
137
|
+
```python
|
138
|
+
# 递归依赖发现
|
139
|
+
def discover_dependencies(message_def):
|
140
|
+
for field in message_def.fields:
|
141
|
+
if field.type_name in custom_types:
|
142
|
+
full_class_name = resolve_type_name(field.type_name)
|
143
|
+
if full_class_name not in processed:
|
144
|
+
queue.append(full_class_name)
|
145
|
+
```
|
146
|
+
|
147
|
+
### 3. 智能类型推断算法
|
148
|
+
```python
|
149
|
+
# 无硬编码的通用推断
|
150
|
+
def infer_type_from_field_name(field_name):
|
151
|
+
clean_name = field_name.rstrip('_')
|
152
|
+
if clean_name.endswith('info'):
|
153
|
+
return to_pascal_case(clean_name)
|
154
|
+
elif clean_name.endswith('data'):
|
155
|
+
return to_pascal_case(clean_name)
|
156
|
+
# ... 更多通用规则
|
157
|
+
```
|
158
|
+
|
159
|
+
## 🎯 设计原则
|
160
|
+
|
161
|
+
### 1. 单一职责原则 (SRP)
|
162
|
+
- 每个模块只负责一个特定的功能
|
163
|
+
- InfoDecoder只负责字节码解码
|
164
|
+
- ProtoGenerator只负责文件生成
|
165
|
+
|
166
|
+
### 2. 开放封闭原则 (OCP)
|
167
|
+
- 通过接口扩展功能,不修改现有代码
|
168
|
+
- 类型推断算法可以轻松添加新规则
|
169
|
+
|
170
|
+
### 3. 依赖倒置原则 (DIP)
|
171
|
+
- 高层模块不依赖低层模块的具体实现
|
172
|
+
- 通过抽象接口进行交互
|
173
|
+
|
174
|
+
### 4. 无硬编码原则
|
175
|
+
- 所有类型推断都基于通用算法
|
176
|
+
- 避免特定应用的硬编码映射
|
177
|
+
|
178
|
+
## 🔧 可扩展性
|
179
|
+
|
180
|
+
### 1. 新增字节码类型支持
|
181
|
+
在`InfoDecoder.type_mapping`中添加新的映射:
|
182
|
+
```python
|
183
|
+
self.type_mapping[new_type_code] = 'new_protobuf_type'
|
184
|
+
```
|
185
|
+
|
186
|
+
### 2. 新增类型推断规则
|
187
|
+
在推断方法中添加新的模式匹配:
|
188
|
+
```python
|
189
|
+
def infer_type_from_field_name(self, field_name):
|
190
|
+
# 添加新的推断规则
|
191
|
+
if field_name.endswith('new_pattern'):
|
192
|
+
return handle_new_pattern(field_name)
|
193
|
+
```
|
194
|
+
|
195
|
+
### 3. 新增输出格式
|
196
|
+
继承`ProtoGenerator`并实现新的生成方法:
|
197
|
+
```python
|
198
|
+
class CustomProtoGenerator(ProtoGenerator):
|
199
|
+
def generate_custom_format(self, message_def):
|
200
|
+
# 实现自定义格式生成
|
201
|
+
```
|
202
|
+
|
203
|
+
## 🚀 性能优化
|
204
|
+
|
205
|
+
### 1. 队列去重
|
206
|
+
使用set进行O(1)的重复检查:
|
207
|
+
```python
|
208
|
+
processed_classes = set()
|
209
|
+
pending_classes = set()
|
210
|
+
```
|
211
|
+
|
212
|
+
### 2. 懒加载
|
213
|
+
只在需要时才解析Java文件和生成proto文件
|
214
|
+
|
215
|
+
### 3. 缓存机制
|
216
|
+
缓存已解析的类型定义,避免重复解析
|
217
|
+
|
218
|
+
## 🧪 测试策略
|
219
|
+
|
220
|
+
### 1. 单元测试
|
221
|
+
- 每个模块独立测试
|
222
|
+
- 模拟输入数据进行测试
|
223
|
+
|
224
|
+
### 2. 集成测试
|
225
|
+
- 端到端的完整流程测试
|
226
|
+
- 真实Android应用的测试用例
|
227
|
+
|
228
|
+
### 3. 回归测试
|
229
|
+
- 对比生成结果与预期输出
|
230
|
+
- 确保修改不破坏现有功能
|
231
|
+
|
232
|
+
## 📈 监控和日志
|
233
|
+
|
234
|
+
### 1. 结构化日志
|
235
|
+
```python
|
236
|
+
logger.info("开始处理类", class_name=class_name, field_count=len(fields))
|
237
|
+
logger.success("生成proto文件", file_path=output_path, size=file_size)
|
238
|
+
```
|
239
|
+
|
240
|
+
### 2. 性能监控
|
241
|
+
- 处理时间统计
|
242
|
+
- 内存使用监控
|
243
|
+
- 文件生成统计
|
244
|
+
|
245
|
+
### 3. 错误追踪
|
246
|
+
- 详细的错误堆栈
|
247
|
+
- 上下文信息记录
|
248
|
+
- 失败重试机制
|
249
|
+
|
250
|
+
## 🔮 未来扩展
|
251
|
+
|
252
|
+
### 1. 多语言支持
|
253
|
+
- 支持生成其他语言的绑定代码
|
254
|
+
- 扩展到其他序列化格式
|
255
|
+
|
256
|
+
### 2. GUI界面
|
257
|
+
- 可视化的操作界面
|
258
|
+
- 拖拽式的配置管理
|
259
|
+
|
260
|
+
### 3. 云端处理
|
261
|
+
- 支持大规模批量处理
|
262
|
+
- 分布式解析能力
|
263
|
+
|
264
|
+
### 4. AI增强
|
265
|
+
- 机器学习辅助类型推断
|
266
|
+
- 智能错误修复建议
|