Skip to content

Commit

Permalink
refactor the code generator and update template
Browse files Browse the repository at this point in the history
  • Loading branch information
mdumandag committed Jan 18, 2021
1 parent 82dd4cf commit b8be733
Show file tree
Hide file tree
Showing 12 changed files with 850 additions and 653 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,3 @@ and they should be in the increasing order of the protocol versions that is 2.1
be in the increasing order of protocol versions as described above.
* Although not necessary, new events or custom types should come after the existing custom types or events on the
protocol definitions.

7 changes: 4 additions & 3 deletions binary/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import struct
from os.path import exists, join

from binary import *
from binary.constants import *
Expand Down Expand Up @@ -26,14 +27,14 @@


def read_definition(definition, protocol_defs_path):
file_path = os.path.join(protocol_defs_path, definition + '.yaml')
file_path = join(protocol_defs_path, definition + '.yaml')
with open(file_path, 'r') as file:
return yaml.load(file, Loader=yaml.Loader)


def get_custom_type_definitions(protocol_defs_path):
custom_codec_defs_path = os.path.join(protocol_defs_path, 'custom')
if not os.path.exists(custom_codec_defs_path):
custom_codec_defs_path = join(protocol_defs_path, 'custom')
if not exists(custom_codec_defs_path):
return {}
definitions = read_definition('Custom', custom_codec_defs_path)
result = {}
Expand Down
98 changes: 65 additions & 33 deletions binary_generator.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,101 @@
#!/usr/bin/env python3

from os import makedirs
from os.path import join

from binary.util import *
from jinja2.exceptions import TemplateNotFound


def get_binary_templates(lang):
env = create_environment_for_binary_generator(lang)
templates = {}
try:
templates['Client'] = env.get_template('client-binary-compatibility-template.j2')
templates['Member'] = env.get_template('member-binary-compatibility-template.j2')
except TemplateNotFound as err:
return err, None
return None, templates
client_template = env.get_template("client-binary-compatibility-template.j2")
member_template = env.get_template("member-binary-compatibility-template.j2")

return {
"Client": client_template,
"Member": member_template,
}


def save_binary_files(binary_output_dir, protocol_defs_path, version, services):
os.makedirs(binary_output_dir, exist_ok=True)
with open(os.path.join(binary_output_dir, version + '.protocol.compatibility.binary'), 'wb') as binary_file:
with open(os.path.join(binary_output_dir, version + '.protocol.compatibility.null.binary'),
'wb') as null_binary_file:
_generate_binary_files(binary_file, null_binary_file, protocol_defs_path, services, version)
makedirs(binary_output_dir, exist_ok=True)
binary_file_path = join(binary_output_dir, version + ".protocol.compatibility.binary")
null_binary_file_path = join(binary_output_dir, version + ".protocol.compatibility.null.binary")

with open(binary_file_path, "wb") as binary_file:
with open(null_binary_file_path, "wb") as null_binary_file:
_generate_binary_files(
binary_file, null_binary_file, protocol_defs_path, services, version
)


def save_test_files(test_output_dir, lang, version, services, templates):
os.makedirs(test_output_dir, exist_ok=True)
makedirs(test_output_dir, exist_ok=True)
class_name = binary_test_names[lang](version)

for test_type in ['Client', 'Member']:
for test_null_type in ['', 'Null']:
with open(os.path.join(test_output_dir, class_name.format(type=test_type, null=test_null_type)), 'w', newline='\n') as f:
f.write(templates[test_type].render(protocol_version=version, services=services, test_nullable=test_null_type == 'Null'))
for test_type in ["Client", "Member"]:
for test_null_type in ["", "Null"]:
file_path = join(
test_output_dir, class_name.format(type=test_type, null=test_null_type)
)
with open(file_path, "w", newline="\n") as f:
f.write(
templates[test_type].render(
protocol_version=version,
services=services,
test_nullable=test_null_type == "Null",
)
)


def _generate_binary_files(binary_file, null_binary_file, protocol_defs_path, services, version):
encoder = Encoder(protocol_defs_path, version)
version_as_number = get_version_as_number(version)
for service in services:
methods = service['methods']
methods = service["methods"]
for method in methods:
if get_version_as_number(method['since']) > version_as_number:
if get_version_as_number(method["since"]) > version_as_number:
continue

method['request']['id'] = int(id_fmt % (service['id'], method['id'], 0), 16)
method['response']['id'] = int(id_fmt % (service['id'], method['id'], 1), 16)
events = method.get('events', None)
method["request"]["id"] = int(id_fmt % (service["id"], method["id"], 0), 16)
method["response"]["id"] = int(id_fmt % (service["id"], method["id"], 1), 16)
events = method.get("events", None)
if events is not None:
for i in range(len(events)):
method['events'][i]['id'] = int(id_fmt % (service['id'], method['id'], i + 2), 16)
request = encoder.encode(method['request'], REQUEST_FIX_SIZED_PARAMS_OFFSET, set_partition_id=True)
null_request = encoder.encode(method['request'], REQUEST_FIX_SIZED_PARAMS_OFFSET,
set_partition_id=True, is_null_test=True)
method["events"][i]["id"] = int(
id_fmt % (service["id"], method["id"], i + 2), 16
)
request = encoder.encode(
method["request"], REQUEST_FIX_SIZED_PARAMS_OFFSET, set_partition_id=True
)
null_request = encoder.encode(
method["request"],
REQUEST_FIX_SIZED_PARAMS_OFFSET,
set_partition_id=True,
is_null_test=True,
)
request.write(binary_file)
null_request.write(null_binary_file)
response = encoder.encode(method['response'], RESPONSE_FIX_SIZED_PARAMS_OFFSET)
null_response = encoder.encode(method['response'], RESPONSE_FIX_SIZED_PARAMS_OFFSET, is_null_test=True)
response = encoder.encode(method["response"], RESPONSE_FIX_SIZED_PARAMS_OFFSET)
null_response = encoder.encode(
method["response"], RESPONSE_FIX_SIZED_PARAMS_OFFSET, is_null_test=True
)
response.write(binary_file)
null_response.write(null_binary_file)
if events is not None:
for e in events:
if get_version_as_number(e['since']) > version_as_number:
if get_version_as_number(e["since"]) > version_as_number:
continue

event = encoder.encode(e, EVENT_FIX_SIZED_PARAMS_OFFSET, is_event=True, set_partition_id=True)
null_event = encoder.encode(e, EVENT_FIX_SIZED_PARAMS_OFFSET, is_event=True,
set_partition_id=True, is_null_test=True)
event = encoder.encode(
e, EVENT_FIX_SIZED_PARAMS_OFFSET, is_event=True, set_partition_id=True
)
null_event = encoder.encode(
e,
EVENT_FIX_SIZED_PARAMS_OFFSET,
is_event=True,
set_partition_id=True,
is_null_test=True,
)
event.write(binary_file)
null_event.write(null_binary_file)
1 change: 1 addition & 0 deletions cs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def cs_escape_keyword(value):
"SqlError": "NA",
"SqlColumnMetadata": "NA",
"CPMember": "Hazelcast.CP.ICPMember",
"MigrationState": "NA",

"List_Long": "ICollection<long>",
"List_Integer": "ICollection<int>",
Expand Down
Loading

0 comments on commit b8be733

Please sign in to comment.