summaryrefslogtreecommitdiffstats
path: root/extras/japi/java/jvpp/gen
diff options
context:
space:
mode:
authorMichal Cmarada <mcmarada@cisco.com>2019-01-31 10:57:40 +0100
committerDamjan Marion <dmarion@me.com>2019-02-19 15:14:02 +0000
commit4e633e1043e867fd24badeb0405f794793beb9a9 (patch)
treeacc92341b32be50bdef030becb2c65efe5252da2 /extras/japi/java/jvpp/gen
parentaed61801947146e6a93e7791d382bd21d050ee14 (diff)
VPP-1504: Remove JVPP
As part of JVPP migration this removes JVPP completely from VPP. Change-Id: I6b74e7961aa474ae471e63fe43a624cd9fc3659b Signed-off-by: Michal Cmarada <mcmarada@cisco.com>
Diffstat (limited to 'extras/japi/java/jvpp/gen')
-rwxr-xr-xextras/japi/java/jvpp/gen/jvpp_gen.py93
-rw-r--r--extras/japi/java/jvpp/gen/jvppgen/__init__.py0
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/callback_gen.py73
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/dto_gen.py231
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/enums_gen.py74
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py482
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jni_gen.py160
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jni_impl_gen.py116
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jni_msg_handlers_gen.py105
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py235
-rw-r--r--extras/japi/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py289
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jvpp_common_gen.py114
-rw-r--r--extras/japi/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py338
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jvpp_ifc_gen.py71
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jvpp_impl_gen.py173
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/jvpp_model.py624
-rw-r--r--extras/japi/java/jvpp/gen/jvppgen/notification_gen.py226
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/types_gen.py60
-rwxr-xr-xextras/japi/java/jvpp/gen/jvppgen/unions_gen.py98
19 files changed, 0 insertions, 3562 deletions
diff --git a/extras/japi/java/jvpp/gen/jvpp_gen.py b/extras/japi/java/jvpp/gen/jvpp_gen.py
deleted file mode 100755
index 067a92f86be..00000000000
--- a/extras/japi/java/jvpp/gen/jvpp_gen.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-import argparse
-import logging
-import os
-import sys
-
-from jvppgen.types_gen import generate_types
-from jvppgen.enums_gen import generate_enums
-from jvppgen.unions_gen import generate_unions
-from jvppgen.dto_gen import generate_dtos
-from jvppgen.jvpp_ifc_gen import generate_java_ifc
-from jvppgen.jvpp_impl_gen import generate_java_impl
-from jvppgen.callback_gen import generate_callbacks
-from jvppgen.jni_gen import generate_jni
-from jvppgen.notification_gen import generate_notifications
-from jvppgen.jvpp_future_facade_gen import generate_future_facade
-from jvppgen.jvpp_callback_facade_gen import generate_callback_facade
-from jvppgen.jvpp_model import JVppModel
-
-
-def generate_jvpp(root_dir, model, logger):
- base_dir = "%s/target/%s" % (root_dir, model.plugin_package.replace(".", "/"))
- generate_types(_work_dir(base_dir, "types"), model, logger)
- generate_enums(_work_dir(base_dir, "types"), model, logger)
- generate_unions(_work_dir(base_dir, "types"), model, logger)
- generate_dtos(_work_dir(base_dir, "dto"), model, logger)
- generate_java_ifc(_work_dir(base_dir), model, logger)
- generate_java_impl(_work_dir(base_dir), model, logger)
- generate_callbacks(_work_dir(base_dir, "callback"), model, logger)
- generate_jni(root_dir, model, logger)
- generate_notifications(_work_dir(base_dir, "notification"), model, logger)
- generate_future_facade(_work_dir(base_dir, "future"), model, logger)
- generate_callback_facade(_work_dir(base_dir, "callfacade"), model, logger)
-
-
-def _work_dir(work_dir, sub_dir=None):
- if sub_dir:
- work_dir = "%s/%s" % (work_dir, sub_dir)
- try:
- os.makedirs(work_dir)
- except OSError:
- if not os.path.isdir(work_dir):
- raise
- return work_dir
-
-
-def _init_logger():
- try:
- verbose = int(os.getenv("V", 0))
- except:
- verbose = 0
-
- log_level = logging.WARNING
- if verbose == 1:
- log_level = logging.INFO
- elif verbose >= 2:
- log_level = logging.DEBUG
-
- logging.basicConfig(stream=sys.stdout, level=log_level)
- logger = logging.getLogger("JVPP GEN")
- logger.setLevel(log_level)
- return logger
-
-
-if __name__ == '__main__':
- logger = _init_logger()
-
- argparser = argparse.ArgumentParser(description="VPP Java API generator")
- argparser.add_argument('-i', nargs='+', metavar='api_file.json', help="json vpp api file(s)")
- argparser.add_argument('--plugin_name')
- argparser.add_argument('--root_dir')
- args = argparser.parse_args()
-
- logger.info("Generating Java API for %s" % args.i)
- logger.debug("plugin_name: %s" % args.plugin_name)
- logger.debug("root_dir: %s" % args.root_dir)
-
- model = JVppModel(logger, args.i, args.plugin_name)
- generate_jvpp(args.root_dir, model, logger)
diff --git a/extras/japi/java/jvpp/gen/jvppgen/__init__.py b/extras/japi/java/jvpp/gen/jvppgen/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/__init__.py
+++ /dev/null
diff --git a/extras/japi/java/jvpp/gen/jvppgen/callback_gen.py b/extras/japi/java/jvpp/gen/jvppgen/callback_gen.py
deleted file mode 100755
index b1ad2013372..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/callback_gen.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jvpp_model import is_request, is_dump, is_control_ping, is_control_ping_reply
-
-
-def generate_callbacks(work_dir, model, logger):
- json_api_files = model.json_api_files
- logger.debug("Generating Callback interfaces for %s" % json_api_files)
- plugin_package = model.plugin_package
-
- callbacks = []
- for msg in model.messages:
- name = msg.java_name_upper
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- if is_dump(msg) or is_request(msg):
- continue
-
- callbacks.append("%s.callback.%sCallback" % (plugin_package, name))
- callback = _CALLBACK_TEMPLATE.substitute(
- plugin_package=plugin_package,
- json_filename=json_api_files,
- name=name)
-
- with open("%s/%sCallback.java" % (work_dir, name), "w") as f:
- f.write(callback)
-
- plugin_name = model.plugin_java_name
- with open("%s/JVpp%sGlobalCallback.java" % (work_dir, plugin_name), "w") as f:
- f.write(_GLOBAL_CALLBACK_TEMPLATE.substitute(
- plugin_package=plugin_package,
- json_filename=json_api_files,
- plugin_name=plugin_name,
- callbacks=", ".join(callbacks)
- ))
-
-_CALLBACK_TEMPLATE = Template("""package $plugin_package.callback;
-
-/**
- * <p>Represents callback for plugin's api message.
- * <br>It was generated by jvppgen/callback_gen.py based on $json_filename.
- */
-public interface ${name}Callback extends io.fd.vpp.jvpp.callback.JVppCallback {
-
- void on${name}(${plugin_package}.dto.${name} reply);
-}
-""")
-
-_GLOBAL_CALLBACK_TEMPLATE = Template("""package $plugin_package.callback;
-
-/**
- * <p>Global aggregated callback interface.
- * <br>It was generated by jvppgen/callback_gen.py based on $json_filename.
- */
-public interface JVpp${plugin_name}GlobalCallback extends io.fd.vpp.jvpp.callback.ControlPingCallback, $callbacks {
-}
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/dto_gen.py b/extras/japi/java/jvpp/gen/jvppgen/dto_gen.py
deleted file mode 100755
index cbd969d51fe..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/dto_gen.py
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from string import Template
-
-from jvpp_common_gen import generate_hash_code, generate_equals, generate_to_string, generate_fields
-from jvpp_model import is_request, is_reply, is_retval, is_dump, is_details, is_event, is_control_ping, \
- is_control_ping_reply
-
-
-def generate_dtos(work_dir, model, logger):
- logger.debug("Generating DTOs for %s " % model.json_api_files)
- _generate_message_dtos(work_dir, model, logger)
- _generate_dump_reply_wrappers(work_dir, model, logger)
-
-
-def _generate_message_dtos(work_dir, model, logger):
- for msg in model.messages:
- logger.debug("Generating DTO for message %s", msg)
- class_name = msg.java_name_upper
-
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- if is_request(msg):
- dto = _generate_request_dto(msg, model, base_type="JVppRequest")
- elif is_dump(msg):
- dto = _generate_request_dto(msg, model, base_type="JVppDump")
- elif is_reply(msg) or is_details(msg):
- dto = _generate_reply_dto(msg, model)
- elif is_event(msg):
- dto = _generate_event_dto(msg, model)
- else:
- logger.warn("Failed to generate DTO for: %s. Message type is not supported." % msg)
- continue
- with open("%s/%s.java" % (work_dir, class_name), "w") as f:
- f.write(dto)
-
-
-def _generate_request_dto(msg, model, base_type):
- msg_java_name_upper = msg.java_name_upper
- fields = msg.fields
- return _REQUEST_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- class_name=msg_java_name_upper,
- base_type=base_type,
- fields=generate_fields(fields),
- hash_code=generate_hash_code(fields),
- equals=generate_equals(msg_java_name_upper, fields),
- to_string=generate_to_string(msg_java_name_upper, fields),
- send=_generate_send(model, msg))
-
-_REQUEST_TEMPLATE = Template("""
-package $plugin_package.dto;
-
-/**
- * <p>This class represents request DTO.
- * <br>It was generated by dto_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public final class $class_name implements io.fd.vpp.jvpp.dto.$base_type {
-$fields
-$hash_code
-$equals
-$to_string
-$send
-}
-""")
-
-
-def _generate_send(model, msg):
- return _SEND_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- plugin_name=model.plugin_java_name,
- method_name=msg.java_name_lower,
- args="this" if msg.has_fields else ""
- )
-
-_SEND_TEMPLATE = Template("""
- @Override
- public int send(final io.fd.vpp.jvpp.JVpp jvpp) throws io.fd.vpp.jvpp.VppInvocationException {
- return (($plugin_package.JVpp${plugin_name})jvpp).$method_name($args);
- }""")
-
-
-def _generate_reply_dto(msg, model):
- msg_java_name_upper = msg.java_name_upper
- # Negative retval is mapped to java exception, so filter it out:
- fields = filter(lambda field: not is_retval(field), msg.fields)
- return _REPLY_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- class_name=msg_java_name_upper,
- request_name=msg.request_java,
- fields=generate_fields(fields),
- hash_code=generate_hash_code(fields),
- equals=generate_equals(msg_java_name_upper, fields),
- to_string=generate_to_string(msg_java_name_upper, fields))
-
-_REPLY_TEMPLATE = Template("""
-package $plugin_package.dto;
-
-/**
- * <p>This class represents reply DTO.
- * <br>It was generated by jvpp_dto_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public final class $class_name implements io.fd.vpp.jvpp.dto.JVppReply<$plugin_package.dto.$request_name> {
-$fields
-$hash_code
-$equals
-$to_string
-}
-""")
-
-
-def _generate_event_dto(msg, model):
- msg_java_name_upper = msg.java_name_upper
- # Negative retval is mapped to java exception, so filter it out:
- fields = filter(lambda field: not is_retval(field), msg.fields)
- return _EVENT_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- class_name=msg_java_name_upper,
- fields=generate_fields(fields),
- hash_code=generate_hash_code(fields),
- equals=generate_equals(msg_java_name_upper, fields),
- to_string=generate_to_string(msg_java_name_upper, fields))
-
-_EVENT_TEMPLATE = Template("""
-package $plugin_package.dto;
-
-/**
- * <p>This class represents event DTO.
- * <br>It was generated by jvpp_dto_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public final class $class_name {
-$fields
-$hash_code
-$equals
-$to_string
-}
-""")
-
-
-def _generate_dump_reply_wrappers(work_dir, model, logger):
- for msg in model.messages:
- if is_details(msg):
- logger.debug("Generating ReplyDump DTO for message %s", msg)
- details_class = msg.java_name_upper
- dto = _REPLY_DUMP_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- details_class=details_class,
- details_field=msg.java_name_lower,
- dump_class=msg.request_java
- )
- with open("%s/%sReplyDump.java" % (work_dir, details_class), "w") as f:
- f.write(dto)
-
-_REPLY_DUMP_TEMPLATE = Template("""
-package $plugin_package.dto;
-
-/**
- * <p>This class represents dump reply wrapper.
- * <br>It was generated by jvpp_dto_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public final class ${details_class}ReplyDump implements io.fd.vpp.jvpp.dto.JVppReplyDump<${plugin_package}.dto.${dump_class}, ${plugin_package}.dto.${details_class}> {
-
- public java.util.List<${details_class}> ${details_field} = new java.util.ArrayList<>();
-
- @Override
- @io.fd.vpp.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD")
- public int hashCode() {
- return java.util.Objects.hash(${details_field});
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- final ${details_class}ReplyDump other = (${details_class}ReplyDump) o;
-
- if (!java.util.Objects.equals(this.${details_field}, other.${details_field})) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public java.lang.String toString() {
- return "${details_class}ReplyDump{" +
- "${details_field}=" + ${details_field} + "}";
- }
-
-
-}
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/enums_gen.py b/extras/japi/java/jvpp/gen/jvppgen/enums_gen.py
deleted file mode 100755
index 8ba96558428..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/enums_gen.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_model import Enum
-
-
-def generate_enums(work_dir, model, logger):
- logger.debug("Generating enums for %s " % model.json_api_files)
-
- for t in model.types:
- if not isinstance(t, Enum):
- continue
- logger.debug("Generating DTO for enum %s", t)
- type_class_name = t.java_name
- type_class = _ENUM_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- c_type_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- java_enum_name=type_class_name,
- constants=_generate_constants(t.constants),
- value_type=t.value.type.java_name
- )
- with open("%s/%s.java" % (work_dir, type_class_name), "w") as f:
- f.write(type_class)
-
-_ENUM_TEMPLATE = Template("""
-package $plugin_package.types;
-
-/**
- * <p>This class represents $c_type_name enum definition.
- * <br>It was generated by enums_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public enum $java_enum_name {
-$constants;
-
- public final $value_type value;
-
- $java_enum_name(final $value_type value) {
- this.value = value;
- }
-
- public static $java_enum_name forValue(final $value_type value) {
- for ($java_enum_name enumeration : $java_enum_name.values()) {
- if (value == enumeration.value) {
- return enumeration;
- }
- }
- return null;
- }
-}
-""")
-
-
-def _generate_constants(constants):
- return ",\n".join(_CONSTANT_TEMPLATE.substitute(name=c['name'], value=c['value']) for c in constants)
-
-_CONSTANT_TEMPLATE = Template(""" $name($value)""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py
deleted file mode 100755
index b52e5ff2d2c..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jni_common_gen.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jvpp_model import is_array, is_retval, Class, Enum, Union
-
-
-def generate_j2c_identifiers(element, class_ref_name, object_ref_name):
- identifiers = []
- for field in element.fields:
- field_type = field.type
- identifiers.append(_REQUEST_FIELD_IDENTIFIER_TEMPLATE.substitute(
- java_name=field.java_name,
- class_ref_name=class_ref_name,
- jni_signature=field_type.jni_signature,
- jni_type=field_type.jni_type,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name
- ))
- return "".join(identifiers)
-
-_REQUEST_FIELD_IDENTIFIER_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}, "${java_name}", "${jni_signature}");
- ${jni_type} ${java_name} = (*env)->Get${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId);
-""")
-
-
-# TODO(VPP-1187): do not inline JNI object creation inside message handlers to reduce number of special cases
-def generate_j2c_swap(element, struct_ref_name, is_alias):
- initialization = []
- for field in element.fields:
- initialization.append(generate_j2c_field_swap(field, struct_ref_name, is_alias))
- return "\n".join(initialization)
-
-
-def generate_j2c_field_swap(field, struct_ref_name, is_alias):
- if is_array(field):
- return _generate_j2c_array_swap(field, struct_ref_name, is_alias)
- else:
- return _generate_j2c_scalar_swap(field, struct_ref_name, is_alias)
-
-
-def _generate_j2c_array_swap(field, struct_ref_name, is_alias):
- # TODO(VPP-1186): move the logic to JNI generators
- base_type = field.type.base_type
- if isinstance(base_type, (Class, Enum, Union)):
- return _generate_j2c_object_array_swap(field, struct_ref_name)
- elif base_type.is_swap_needed:
- return _generate_j2c_primitive_type_array_swap(field, struct_ref_name)
- else:
- return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias)
-
-
-def _generate_j2c_object_array_swap(field, struct_ref_name):
- field_type = field.type
- field_reference_name = field.java_name
- c_name = field.name
- host = "%sArrayElement" % field_reference_name
- net = "%s->%s[_i]" % (struct_ref_name, c_name)
- swap_elements = field_type.get_host_to_net_function(host, net)
- return _J2C_OBJECT_ARRAY_SWAP_TEMPLATE.substitute(
- field_reference_name=field_reference_name,
- field_length_check=_generate_field_length_check(field),
- swap_elements=swap_elements)
-
-_J2C_OBJECT_ARRAY_SWAP_TEMPLATE = Template("""
- {
- if (${field_reference_name}) {
- size_t _i;
- jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
- ${field_length_check}
- for (_i = 0; _i < cnt; _i++) {
- jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i);
- ${swap_elements};
- }
- }
- }
-""")
-
-
-def _generate_j2c_primitive_type_array_swap(field, struct_ref_name):
- field_reference_name = field.java_name
- field_type = field.type
- host = "%sArrayElements[_i]" % field_reference_name
- net = "%s->%s[_i]" % (struct_ref_name, field.name)
- swap_elements = field_type.get_host_to_net_function(host, net)
- return _J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
- field_reference_name=field_reference_name,
- field_length_check=_generate_field_length_check(field),
- base_type=field_type.base_type.jni_accessor,
- jni_base_type=field_type.base_type.jni_type,
- swap_elements=swap_elements
- )
-
-_J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
- if (${field_reference_name}) {
- ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
- size_t _i;
- jsize cnt = (*env)->GetArrayLength(env, ${field_reference_name});
- ${field_length_check}
- for (_i = 0; _i < cnt; _i++) {
- ${swap_elements};
- }
- (*env)->Release${base_type}ArrayElements (env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
- }
- """)
-
-
-def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias):
- field_type = field.type
- if not is_alias:
- template = _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
- else:
- template = _J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
-
- return template.substitute(
- field_reference_name=field.java_name,
- field_length_check=_generate_field_length_check(field),
- base_type=field_type.base_type.jni_accessor,
- jni_base_type=field_type.base_type.jni_type,
- struct_reference_name=struct_ref_name,
- c_name=field.name
- )
-
-_J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
- if (${field_reference_name}) {
- jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
- ${field_length_check}
- (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}->${c_name});
- }
-""")
-
-
-_J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
- if (${field_reference_name}) {
- jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
- ${field_length_check}
- (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name});
- }
-""")
-
-
-def _generate_field_length_check(field):
- # Enforce max length if array has fixed length or uses variable length syntax
- field_length = str(field.array_len)
- if field.array_len_field:
- field_length = field.array_len_field.java_name
-
- # TODO: remove when ZLAs without length field are disabled
- if field_length != "0":
- return _FIELD_LENGTH_CHECK.substitute(field_length=field_length)
- else:
- return ""
-
-
-# Make sure we do not write more elements that are expected
-_FIELD_LENGTH_CHECK = Template("""
- size_t max_size = ${field_length};
- if (cnt > max_size) cnt = max_size;""")
-
-
-def _generate_j2c_scalar_swap(field, struct_ref_name, is_alias):
- field_type = field.type
- if field_type.is_swap_needed:
- host = field.java_name
- if not is_alias:
- net = "%s->%s" % (struct_ref_name, field.name)
- if field_type.name == "string":
- net = "%s->%s" % (struct_ref_name, field.name)
- return " _host_to_net_%s(env, %s, (vl_api_string_t *) &%s);" % (field_type.name, host, net)
- else:
- return " %s;" % field_type.get_host_to_net_function(host, net)
- else:
- net = "%s" % struct_ref_name
- return " *%s;" % field_type.get_host_to_net_function(host, net)
- else:
- return " %s->%s = %s;" % (struct_ref_name, field.name, field.java_name)
-
-
-def generate_c2j_swap(element, object_ref_name, struct_ref_name, is_alias):
- msg_java_name = element.java_name_lower
- initialization = []
- for field in element.fields:
- if is_retval(field):
- # For retval don't generate setters and generate retval check
- continue
- elif is_array(field):
- initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
- else:
- initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
- return "".join(initialization)
-
-
-def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
- # TODO(VPP-1186): move the logic to JNI generators
- base_type = field.type.base_type
- if isinstance(base_type, (Class, Union)):
- return _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
- elif isinstance(base_type, Enum):
- return _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
- elif base_type.is_swap_needed:
- return _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
- else:
- return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
-
-
-def _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- return _C2J_OBJECT_ARRAY_SWAP_TEMPLATE.substitute(
- field_reference_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_name=field_type.base_type.jni_name,
- field_length=_generate_array_length(field, struct_ref_name),
- net_to_host_function=field_type.net_to_host_function,
- struct_ref_name=struct_ref_name,
- object_ref_name=object_ref_name,
- c_name=field.name
- )
-
-_C2J_OBJECT_ARRAY_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- {
- jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
- jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
- jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
- unsigned int _i;
- for (_i = 0; _i < ${field_length}; _i++) {
- jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor);
- ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}[_i]), ${field_reference_name}ArrayElement);
- (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
- (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
- }
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
- }
-""")
-
-
-def _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- base_type = field_type.base_type
- return _C2J_ENUM_ARRAY_SWAP_TEMPLATE.substitute(
- field_reference_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_name=base_type.jni_name,
- field_length=_generate_array_length(field, struct_ref_name),
- net_to_host_function=field_type.net_to_host_function,
- jni_signature_enum_value=base_type.value.type.jni_signature,
- struct_ref_name=struct_ref_name,
- object_ref_name=object_ref_name,
- c_name=field.name
- )
-
-_C2J_ENUM_ARRAY_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- {
- jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
- jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
- jmethodID ${field_reference_name}Constructor = (*env)->GetStaticMethodID(env, ${field_reference_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}");
- unsigned int _i;
- for (_i = 0; _i < ${field_length}; _i++) {
- jobject ${field_reference_name}ArrayElement = (*env)->CallStaticObjectMethod(env, ${field_reference_name}Class, ${field_reference_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]));
- (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
- (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
- }
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
- }
-""")
-
-
-def _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- return _C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
- field_reference_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_type=field_type.jni_type,
- base_type=field_type.base_type.jni_accessor,
- field_length=_generate_array_length(field, struct_ref_name),
- jni_base_type=field_type.base_type.jni_type,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- c_name=field.name
- )
-
-_C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- {
- ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
- ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
- unsigned int _i;
- for (_i = 0; _i < ${field_length}; _i++) {
- ${field_reference_name}ArrayElements[_i] = ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]);
- }
-
- (*env)->Release${base_type}ArrayElements(env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
- }
-""")
-
-
-def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
- field_type = field.type
- if not is_alias:
- template = _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
- else:
- template = _C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
- return template.substitute(
- field_reference_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_type=field_type.jni_type,
- base_type=field_type.base_type.jni_accessor,
- field_length=_generate_array_length(field, struct_ref_name),
- jni_base_type=field_type.base_type.jni_type,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- c_name=field.name
- )
-
-_C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
- (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}->${c_name});
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
-""")
-
-
-_C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
- (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name});
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
-""")
-
-
-def _generate_array_length(field, struct_ref_name):
- if field.array_len_field:
- len_field = field.array_len_field
- if len_field.type.is_swap_needed:
- return "%s(%s->%s)" % (len_field.type.host_to_net_function, struct_ref_name, len_field.name)
- else:
- return "%s->%s" % (struct_ref_name, len_field.name)
- return field.array_len
-
-
-def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
- field_type = field.type
- if field_type.is_swap_needed:
- # TODO(VPP-1186): move the logic to JNI generators
- if isinstance(field_type, (Class, Union)):
- return _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name)
- elif isinstance(field_type, Enum):
- return _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name)
- else:
- return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
- else:
- return _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
-
-
-def _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- return _C2J_OBJECT_SWAP_TEMPLATE.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_name=field_type.jni_name,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- c_name=field.name)
-
-_C2J_OBJECT_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
- jmethodID ${java_name}Constructor = (*env)->GetMethodID(env, ${java_name}Class, "<init>", "()V");
- jobject ${java_name} = (*env)->NewObject(env, ${java_name}Class, ${java_name}Constructor);
- ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}), ${java_name});
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
- (*env)->DeleteLocalRef(env, ${java_name});
-""")
-
-
-def _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- return _C2J_ENUM_SWAP_TEMPLATE.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_signature_enum_value=field_type.value.type.jni_signature,
- jni_name=field_type.jni_name,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- c_name=field.name)
-
-_C2J_ENUM_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
- jmethodID ${java_name}Constructor = (*env)->GetStaticMethodID(env, ${java_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}");
- jobject ${java_name} = (*env)->CallStaticObjectMethod(env, ${java_name}Class, ${java_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name}));
- (*env)->SetObjectField(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
- (*env)->DeleteLocalRef(env, ${java_name});
-""")
-
-
-def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
- field_type = field.type
- if not is_alias:
- if field_type.name == "string":
- template = _C2J_STRING_TYPE_SWAP_TEMPLATE
- else:
- template = _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE
- else:
- template = _C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE
- return template.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- struct_ref_name=struct_ref_name,
- c_name=field.name
- )
-
-_C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(${struct_ref_name}->${c_name}));
-""")
-
-
-_C2J_STRING_TYPE_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(env, (const vl_api_string_t *) &${struct_ref_name}->${c_name}));
-""")
-
-
-_C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(*${struct_ref_name}));
-""")
-
-
-def _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
- field_type = field.type
- return _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- c_name=field.name
- )
-
-_C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${struct_ref_name}->${c_name});
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_gen.py
deleted file mode 100755
index ad6c2614062..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jni_gen.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jni_impl_gen import generate_jni_impl
-from jni_msg_handlers_gen import generate_jni_handlers
-from jni_type_handlers_gen import generate_type_handlers
-from jvpp_model import is_control_ping, is_dump, is_request, is_control_ping_reply
-
-
-def generate_jni(work_dir, model, logger):
- logger.debug("Generating jvpp C for %s" % model.json_api_files)
- plugin_name = model.plugin_name
- messages = model.messages
-
- with open("%s/jvpp_%s_gen.h" % (work_dir, plugin_name), "w") as f:
- f.write(_JVPP_C_TEMPLATE.substitute(
- json_filename=model.json_api_files,
- class_cache=_generate_class_cache(plugin_name, messages),
- api_verification=_generate_api_verification(messages),
- type_handlers=generate_type_handlers(model, logger),
- jni_implementations=generate_jni_impl(model),
- msg_handlers=generate_jni_handlers(model),
- handler_registration=_generate_handler_registration(messages)))
-
-_JVPP_C_TEMPLATE = Template("""/**
- * This file contains JNI bindings for jvpp Java API.
- * It was generated by jvpp_jni_gen.py based on $json_filename.
- */
-$class_cache
-
-$api_verification
-
-// Type handlers
-$type_handlers
-
-// JNI bindings
-$jni_implementations
-
-// Message handlers
-$msg_handlers
-
-$handler_registration
-""")
-
-
-def _generate_class_cache(plugin_name, messages):
- references = []
- for msg in messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- references.append((
- msg.java_name_lower,
- 'io/fd/vpp/jvpp/%s/dto/%s' % (plugin_name, msg.java_name_upper)
- ))
-
- references.append(('callbackException', 'io/fd/vpp/jvpp/VppCallbackException'))
-
- return _CLASS_CACHE_TEMPLATE.substitute(
- class_references=_generate_class_references(references),
- create_references=_generate_create_references(references),
- delete_references=_generate_delete_references(references)
- )
-
-_CLASS_CACHE_TEMPLATE = Template("""
-// JAVA class reference cache
-$class_references
-
-static int cache_class_references(JNIEnv* env) {
-$create_references
- return 0;
-}
-
-static void delete_class_references(JNIEnv* env) {
-$delete_references
-}""")
-
-
-def _generate_class_references(references):
- return "\n".join("jclass %sClass;" % r[0] for r in references)
-
-
-def _generate_create_references(references):
- items = []
- for r in references:
- items.append(_CREATE_GLOBAL_REF_TEMPLATE.substitute(
- ref_name=r[0],
- fqn_name=r[1]
- ))
- return "".join(items)
-
-_CREATE_GLOBAL_REF_TEMPLATE = Template("""
- ${ref_name}Class = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "${fqn_name}"));
- if ((*env)->ExceptionCheck(env)) {
- (*env)->ExceptionDescribe(env);
- return JNI_ERR;
- }""")
-
-
-def _generate_delete_references(references):
- items = []
- for r in references:
- items.append(_DELETE_CLASS_INVOCATION_TEMPLATE.substitute(ref_name=r[0]))
- return "".join(items)
-
-_DELETE_CLASS_INVOCATION_TEMPLATE = Template("""
- if (${ref_name}Class) {
- (*env)->DeleteGlobalRef(env, ${ref_name}Class);
- }""")
-
-
-def _generate_api_verification(messages):
- items = []
- for msg in messages:
- items.append("_(%s_%s) \\" % (msg.name, msg.crc))
- return _API_VERIFICATION_TEMPLATE.substitute(messages="\n".join(items))
-
-_API_VERIFICATION_TEMPLATE = Template("""
-// List of supported API messages used for verification
-#define foreach_supported_api_message \\
-$messages
-""")
-
-
-def _generate_handler_registration(messages):
- """
- Generates msg handler registration for all messages except for dumps and requests.
- :param messages: collection of VPP API messages.
- """
- handlers = []
- for msg in messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- if is_dump(msg) or is_request(msg):
- continue
- name = msg.name
- crc = msg.crc
- handlers.append("_(%s_%s, %s) \\" % (name, crc, name))
- return _HANDLER_REGISTRATION_TEMPLATE.substitute(handlers="\n".join(handlers))
-
-_HANDLER_REGISTRATION_TEMPLATE = Template("""
-// Registration of message handlers in vlib
-#define foreach_api_reply_handler \\
-$handlers
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_impl_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_impl_gen.py
deleted file mode 100755
index 2941778f208..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jni_impl_gen.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jni_common_gen import generate_j2c_identifiers, generate_j2c_swap
-from jvpp_model import is_dump, is_request, is_control_ping, is_control_ping_reply
-
-
-def generate_jni_impl(model):
- """
- Generates JNI bindings for sending dump and request messages.
- :param model: meta-model of VPP API used for jVPP generation.
- """
- jni_impl = []
- for msg in model.messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control ping managed by jvpp registry.
- continue
- if not (is_dump(msg) or is_request(msg)):
- continue
- arguments = ""
- request_class = ""
- jni_identifiers = ""
- msg_initialization = ""
-
- if msg.has_fields:
- arguments = ", jobject request"
- request_class = _REQUEST_CLASS_TEMPLATE.substitute(
- plugin_name=model.plugin_name,
- java_dto_name=msg.java_name_upper
- )
- jni_identifiers = generate_j2c_identifiers(msg, class_ref_name="requestClass", object_ref_name="request")
- msg_initialization = generate_j2c_swap(msg, struct_ref_name="mp", is_alias=False)
-
- jni_impl.append(_JNI_IMPL_TEMPLATE.substitute(
- c_name=msg.name,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- plugin_name=model.plugin_name,
- plugin_java_name=model.plugin_java_name,
- java_method_name=msg.java_name_lower,
- arguments=arguments,
- request_class=request_class,
- jni_identifiers=jni_identifiers,
- msg_size=_generate_msg_size(msg),
- crc=msg.crc,
- msg_initialization=msg_initialization
- ))
- return "".join(jni_impl)
-
-
-_JNI_IMPL_TEMPLATE = Template("""
-/**
- * JNI binding for sending ${c_name} message.
- * Generated based on $json_filename:
-$json_definition
- */
-JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${plugin_java_name}Impl_${java_method_name}0
-(JNIEnv * env, jclass clazz${arguments}) {
- ${plugin_name}_main_t *plugin_main = &${plugin_name}_main;
- vl_api_${c_name}_t * mp;
- u32 my_context_id = vppjni_get_context_id (&jvpp_main);
-$request_class
-$jni_identifiers
-
- // create message:
- const size_t _size = ${msg_size};
- mp = vl_msg_api_alloc(_size);
- memset (mp, 0, _size);
- mp->_vl_msg_id = ntohs (get_message_id(env, "${c_name}_${crc}"));
- mp->client_index = plugin_main->my_client_index;
- mp->context = clib_host_to_net_u32 (my_context_id);
-
-$msg_initialization
-
- // send message:
- if (CLIB_DEBUG > 1)
- clib_warning ("Sending ${c_name} message");
- vl_msg_api_send_shmem (plugin_main->vl_input_queue, (u8 *)&mp);
- if ((*env)->ExceptionCheck(env)) {
- return JNI_ERR;
- }
- return my_context_id;
-}""")
-
-# TODO: cache method and field identifiers to achieve better performance
-# https://jira.fd.io/browse/HONEYCOMB-42
-_REQUEST_CLASS_TEMPLATE = Template(""" jclass requestClass = (*env)->FindClass(env, "io/fd/vpp/jvpp/${plugin_name}/dto/${java_dto_name}");
-""")
-
-
-def _generate_msg_size(msg):
- msg_size = "sizeof(*mp)"
- _size_components = []
- for field in msg.fields:
- # Ignore ZLAs for simplicity (to support them we need to call JNI functions to check actual size)
- if field.array_len_field:
- _size_components += " + %s*sizeof(%s)" % (field.array_len_field.java_name, field.type.base_type.vpp_name)
- # FIXME(VPP-586): for proper nested structures support, we need generate functions computing type sizes
- # and use it instead of sizeof
- if field.type.name == "string":
- _size_components += " + jstr_length(env, %s) * sizeof(u8)" % field.name
- return msg_size + "".join(_size_components)
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_msg_handlers_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_msg_handlers_gen.py
deleted file mode 100755
index 5f274a3e1dd..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jni_msg_handlers_gen.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jni_common_gen import generate_c2j_swap
-from jvpp_model import is_dump, is_request, is_control_ping, is_control_ping_reply, is_retval
-
-
-def generate_jni_handlers(model):
- """
- Generates msg handlers for all messages except for dumps and requests (handled by vpp, not client).
- :param model: meta-model of VPP API used for jVPP generation.
- """
- jni_impl = []
- for msg in model.messages:
- msg_name = msg.name
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control ping managed by jvpp registry.
- continue
- if is_dump(msg) or is_request(msg):
- continue
-
- jni_impl.append(_MSG_HANDLER_TEMPLATE.substitute(
- c_name=msg_name,
- json_filename=model.json_api_files,
- json_definition=msg.doc,
- plugin_name=model.plugin_name,
- err_handler=_generate_error_handler(msg),
- class_ref_name=msg.java_name_lower,
- dto_name=msg.java_name_upper,
- dto_setters=generate_c2j_swap(msg, object_ref_name="dto", struct_ref_name="mp", is_alias=False)
- ))
- return "".join(jni_impl)
-
-_MSG_HANDLER_TEMPLATE = Template("""
-/**
- * Handler for ${c_name} message.
- * Generated based on $json_filename:
-$json_definition
- */
-static void vl_api_${c_name}_t_handler (vl_api_${c_name}_t * mp)
-{
- ${plugin_name}_main_t *plugin_main = &${plugin_name}_main;
- JNIEnv *env = jvpp_main.jenv;
- jthrowable exc;
-$err_handler
-
- if (CLIB_DEBUG > 1)
- clib_warning ("Received ${c_name} event message");
-
- jmethodID constructor = (*env)->GetMethodID(env, ${class_ref_name}Class, "<init>", "()V");
-
- // User does not have to provide callbacks for all VPP messages.
- // We are ignoring messages that are not supported by user.
- (*env)->ExceptionClear(env); // just in case exception occurred in different place and was not properly cleared
- jmethodID callbackMethod = (*env)->GetMethodID(env, plugin_main->callbackClass, "on${dto_name}", "(Lio/fd/vpp/jvpp/${plugin_name}/dto/${dto_name};)V");
- exc = (*env)->ExceptionOccurred(env);
- if (exc) {
- clib_warning("Unable to extract on${dto_name} method reference from ${plugin_name} plugin's callbackClass. Ignoring message.\\n");
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
- return;
- }
-
- jobject dto = (*env)->NewObject(env, ${class_ref_name}Class, constructor);
-$dto_setters
-
- (*env)->CallVoidMethod(env, plugin_main->callbackObject, callbackMethod, dto);
- // free DTO as per http://stackoverflow.com/questions/1340938/memory-leak-when-calling-java-code-from-c-using-jni
- (*env)->DeleteLocalRef(env, dto);
-}""")
-
-
-def _generate_error_handler(msg):
- err_handler = ""
- for field in msg.fields:
- if is_retval(field):
- err_handler = _ERR_HANDLER_TEMPLATE.substitute(name=msg.name)
- return err_handler
-
-# Code fragment for checking result of the operation before sending request reply.
-# Error checking is optional (some messages, e.g. detail messages do not have retval field).
-_ERR_HANDLER_TEMPLATE = Template("""
- // for negative result don't send callback message but send error callback
- if (mp->retval<0) {
- call_on_error("${name}", mp->context, mp->retval, plugin_main->callbackClass, plugin_main->callbackObject, callbackExceptionClass);
- return;
- }
- if (mp->retval == VNET_API_ERROR_IN_PROGRESS) {
- clib_warning("Result in progress");
- return;
- }""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py
deleted file mode 100755
index 59aaf95065a..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jni_common_gen import generate_j2c_swap, generate_j2c_field_swap, generate_j2c_identifiers, generate_c2j_swap
-from jvpp_model import Class, Enum, Union
-
-
-def generate_type_handlers(model, logger):
- """
- Generates host-to-net and net-to-host functions for all custom types defined in the VPP API
- :param model: meta-model of VPP API used for jVPP generation.
- :param logger: jVPP logger
- """
- type_handlers = []
- for t in model.types:
- #TODO(VPP-1186): move the logic to JNI generators
- if isinstance(t, Class):
- _generate_class(model, t, type_handlers)
- elif isinstance(t, Enum):
- _generate_enum(model, t, type_handlers)
- elif isinstance(t, Union):
- _generate_union(model, t, type_handlers)
- else:
- logger.debug("Skipping custom JNI type handler generation for %s", t)
-
- return "\n".join(type_handlers)
-
-
-def _generate_class(model, t, type_handlers):
- ref_name = t.java_name_lower
- if t.name in model._aliases:
- is_alias = True
- else:
- is_alias = False
-
- type_handlers.append(_TYPE_HOST_TO_NET_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- type_reference_name=ref_name,
- class_FQN=t.jni_name,
- jni_identifiers=generate_j2c_identifiers(t, class_ref_name="%sClass" % ref_name, object_ref_name="_host"),
- type_swap=generate_j2c_swap(t, struct_ref_name="_net", is_alias=is_alias)
- ))
- type_handlers.append(_TYPE_NET_TO_HOST_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- type_reference_name=ref_name,
- class_FQN=t.jni_name,
- type_swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net", is_alias=is_alias)
- ))
-
-_TYPE_HOST_TO_NET_TEMPLATE = Template("""
-/**
- * Host to network byte order conversion for ${c_name} type.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline void _host_to_net_${c_name}(JNIEnv * env, jobject _host, vl_api_${c_name}_t * _net)
-{
- jclass ${type_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
-$jni_identifiers
-$type_swap
-}""")
-
-_TYPE_NET_TO_HOST_TEMPLATE = Template("""
-/**
- * Network to host byte order conversion for ${c_name} type.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline void _net_to_host_${c_name}(JNIEnv * env, vl_api_${c_name}_t * _net, jobject _host)
-{
- jclass ${type_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
-$type_swap
-}""")
-
-
-def _generate_enum(model, t, type_handlers):
- value_type = t.value.type
- type_handlers.append(_ENUM_NET_TO_HOST_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- class_FQN=t.jni_name,
- jni_signature=value_type.jni_signature,
- jni_type=value_type.jni_type,
- jni_accessor=value_type.jni_accessor,
- swap=_generate_scalar_host_to_net_swap(t.value)
- ))
-
- type_handlers.append(_ENUM_HOST_TO_NET_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- class_FQN=t.jni_name,
- jni_type=value_type.jni_type,
- type_swap=_generate_scalar_net_to_host_swap(t.value)
- ))
-
-_ENUM_NET_TO_HOST_TEMPLATE = Template("""
-/**
- * Host to network byte order conversion for ${c_name} enum.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline void _host_to_net_${c_name}(JNIEnv * env, jobject _host, vl_api_${c_name}_t * _net)
-{
- jclass enumClass = (*env)->FindClass(env, "${class_FQN}");
- jmethodID getValueMethod = (*env)->GetMethodID(env, enumClass, "ordinal", "()I");
- ${jni_type} value = (*env)->CallIntMethod(env, _host, getValueMethod);
- ${swap};
-}""")
-
-_ENUM_HOST_TO_NET_TEMPLATE = Template("""
-/**
- * Network to host byte order conversion for ${c_name} type.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline ${jni_type} _net_to_host_${c_name}(vl_api_${c_name}_t _net)
-{
- return (${jni_type}) $type_swap
-}""")
-
-
-def _generate_scalar_host_to_net_swap(field):
- field_type = field.type
- if field_type.is_swap_needed:
- return field_type.get_host_to_net_function(field.java_name, "*_net")
- else:
- return "*_net = %s" % field.java_name
-
-
-def _generate_scalar_net_to_host_swap(field):
- field_type = field.type
- if field_type.is_swap_needed:
- return "%s((%s) _net);" % (field_type.net_to_host_function, field_type.name)
- else:
- return "_net"
-
-
-def _generate_union(model, t, type_handlers):
- type_handlers.append(_generate_union_host_to_net(model, t))
- type_handlers.append(_generate_union_net_to_host(model, t))
-
-
-def _generate_union_host_to_net(model, t):
- swap = []
- for i, field in enumerate(t.fields):
- field_type = field.type
- if t.name in model._aliases:
- is_alias = True
- else:
- is_alias = False
- swap.append(_UNION_FIELD_HOST_TO_NET_TEMPLATE.substitute(
- field_index=i,
- java_name=field.java_name,
- jni_signature=field_type.jni_signature,
- jni_type=field_type.jni_type,
- jni_accessor=field_type.jni_accessor,
- swap=generate_j2c_field_swap(field, struct_ref_name="_net", is_alias=is_alias)
- ))
-
- return _UNION_HOST_TO_NET_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- class_FQN=t.jni_name,
- swap="".join(swap)
- )
-
-_UNION_FIELD_HOST_TO_NET_TEMPLATE = Template("""
- if (_activeMember == ${field_index}) {
- jfieldID fieldId = (*env)->GetFieldID(env, _class, "${java_name}", "${jni_signature}");
- ${jni_type} ${java_name} = (*env)->Get${jni_accessor}Field(env, _host, fieldId);
- ${swap}
- }""")
-
-_UNION_HOST_TO_NET_TEMPLATE = Template("""
-/**
- * Host to network byte order conversion for ${c_name} union.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline void _host_to_net_${c_name}(JNIEnv * env, jobject _host, vl_api_${c_name}_t * _net)
-{
- jclass _class = (*env)->FindClass(env, "${class_FQN}");
-
- jfieldID _activeMemberFieldId = (*env)->GetFieldID(env, _class, "_activeMember", "I");
- jint _activeMember = (*env)->GetIntField(env, _host, _activeMemberFieldId);
-$swap
-}""")
-
-
-def _generate_union_net_to_host(model, t):
- if t.name in model._aliases:
- is_alias = True
- else:
- is_alias = False
- return _UNION_NET_TO_HOST_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- type_reference_name=t.java_name_lower,
- class_FQN=t.jni_name,
- swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net", is_alias=is_alias)
- )
-
-_UNION_NET_TO_HOST_TEMPLATE = Template("""
-/**
- * Network to host byte order conversion for ${c_name} union.
- * Generated based on $json_filename:
-$json_definition
- */
-static inline void _net_to_host_${c_name}(JNIEnv * env, vl_api_${c_name}_t * _net, jobject _host)
-{
- jclass ${type_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
-$swap
-}""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py
deleted file mode 100644
index ebc552bfda6..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_model import is_control_ping, is_dump, is_request, is_event, is_control_ping_reply
-
-
-def generate_callback_facade(work_dir, model, logger):
- """ Generates callback facade """
- logger.debug("Generating JVpp callback facade for %s" % model.json_api_files)
- _generate_ifc(work_dir, model),
- _generate_impl(work_dir, model)
- _generate_callback(work_dir, model)
-
-
-def _generate_ifc(work_dir, model):
- with open("%s/CallbackJVpp%s.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_IFC_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_ifc_methods(model)
- ))
-
-_IFC_TEMPLATE = Template("""
-package $plugin_package.callfacade;
-
-/**
- * <p>Callback Java API representation of $plugin_package plugin.
- * <br>It was generated by jvpp_callback_facade_gen.py based on $json_filename.
- */
-public interface CallbackJVpp${plugin_name} extends io.fd.vpp.jvpp.notification.EventRegistryProvider, java.lang.AutoCloseable {
-
- // TODO add send
-
-$methods
-}
-""")
-
-
-def _generate_ifc_methods(model):
- plugin_package = model.plugin_package
- methods = []
- for msg in model.messages:
- if is_control_ping(msg):
- # Skip control ping managed by jvpp registry.
- continue
- if not (is_dump(msg) or is_request(msg)):
- # Skip replies and messages that do not not have replies (e.g events/counters).
- continue
- template = _IFC_NO_ARG_METHOD_TEMPLATE
- if msg.has_fields:
- template = _IFC_METHOD_TEMPLATE
- methods.append(template.substitute(
- name=msg.java_name_lower,
- plugin_package=plugin_package,
- request=msg.java_name_upper,
- reply=msg.reply_java
- ))
- return "\n".join(methods)
-
-_IFC_NO_ARG_METHOD_TEMPLATE = Template(
- """ void $name($plugin_package.callback.${reply}Callback callback) throws io.fd.vpp.jvpp.VppInvocationException;""")
-
-_IFC_METHOD_TEMPLATE = Template(
- """ void $name($plugin_package.dto.$request request, $plugin_package.callback.${reply}Callback callback) throws io.fd.vpp.jvpp.VppInvocationException;""")
-
-
-def _generate_impl(work_dir, model):
- with open("%s/CallbackJVpp%sFacade.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_IMPL_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_impl_methods(model)
- ))
-
-_IMPL_TEMPLATE = Template("""
-package $plugin_package.callfacade;
-
-/**
- * <p>Default implementation of Callback${plugin_name}JVpp interface.
- * <br>It was generated by jvpp_callback_facade_gen.py based on $json_filename.
- */
-public final class CallbackJVpp${plugin_name}Facade implements CallbackJVpp${plugin_name} {
-
- private final $plugin_package.JVpp${plugin_name} jvpp;
- private final java.util.Map<Integer, io.fd.vpp.jvpp.callback.JVppCallback> callbacks;
- private final $plugin_package.notification.${plugin_name}EventRegistryImpl eventRegistry = new $plugin_package.notification.${plugin_name}EventRegistryImpl();
- /**
- * <p>Create CallbackJVpp${plugin_name}Facade object for provided JVpp instance.
- * Constructor internally creates CallbackJVppFacadeCallback class for processing callbacks
- * and then connects to provided JVpp instance
- *
- * @param jvpp provided io.fd.vpp.jvpp.JVpp instance
- *
- * @throws java.io.IOException in case instance cannot connect to JVPP
- */
- public CallbackJVpp${plugin_name}Facade(final io.fd.vpp.jvpp.JVppRegistry registry, final $plugin_package.JVpp${plugin_name} jvpp) throws java.io.IOException {
- this.jvpp = java.util.Objects.requireNonNull(jvpp,"jvpp is null");
- this.callbacks = new java.util.HashMap<>();
- java.util.Objects.requireNonNull(registry, "JVppRegistry should not be null");
- registry.register(jvpp, new CallbackJVpp${plugin_name}FacadeCallback(this.callbacks, eventRegistry));
- }
-
- @Override
- public $plugin_package.notification.${plugin_name}EventRegistry getEventRegistry() {
- return eventRegistry;
- }
-
- @Override
- public void close() throws Exception {
- jvpp.close();
- }
-
- // TODO add send()
-
-$methods
-}
-""")
-
-
-def _generate_impl_methods(model):
- plugin_package = model.plugin_package
- methods = []
- for msg in model.messages:
- if is_control_ping(msg):
- # Skip control ping managed by jvpp registry.
- continue
- if not (is_dump(msg) or is_request(msg)):
- # Skip replies and messages that do not not have replies (e.g events/counters).
- continue
- template = _IMPL_NO_ARG_METHOD_TEMPLATE
- if msg.has_fields:
- template = _IMPL_METHOD_TEMPLATE
- methods.append(template.substitute(
- name=msg.java_name_lower,
- plugin_package=plugin_package,
- request=msg.java_name_upper,
- reply=msg.reply_java
- ))
- return "\n".join(methods)
-
-_IMPL_NO_ARG_METHOD_TEMPLATE = Template(
- """ public final void $name($plugin_package.callback.${reply}Callback callback) throws io.fd.vpp.jvpp.VppInvocationException {
- synchronized (callbacks) {
- callbacks.put(jvpp.$name(), callback);
- }
- }
-""")
-
-_IMPL_METHOD_TEMPLATE = Template(""" public final void $name($plugin_package.dto.$request request, $plugin_package.callback.${reply}Callback callback) throws io.fd.vpp.jvpp.VppInvocationException {
- synchronized (callbacks) {
- callbacks.put(jvpp.$name(request), callback);
- }
- }
-""")
-
-
-def _generate_callback(work_dir, model):
- with open("%s/CallbackJVpp%sFacadeCallback.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_CALLBACK_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_callback_methods(model)
- ))
-
-_CALLBACK_TEMPLATE = Template("""
-package $plugin_package.callfacade;
-
-/**
- * <p>Implementation of JVppGlobalCallback interface for Java Callback API.
- * <br>It was generated by jvpp_callback_facade_gen.py based on $json_filename.
- */
-public final class CallbackJVpp${plugin_name}FacadeCallback implements $plugin_package.callback.JVpp${plugin_name}GlobalCallback {
-
- private final java.util.Map<Integer, io.fd.vpp.jvpp.callback.JVppCallback> requests;
- private final $plugin_package.notification.Global${plugin_name}EventCallback eventCallback;
- private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CallbackJVpp${plugin_name}FacadeCallback.class.getName());
-
- public CallbackJVpp${plugin_name}FacadeCallback(final java.util.Map<Integer, io.fd.vpp.jvpp.callback.JVppCallback> requestMap,
- final $plugin_package.notification.Global${plugin_name}EventCallback eventCallback) {
- this.requests = requestMap;
- this.eventCallback = eventCallback;
- }
-
- @Override
- public void onError(io.fd.vpp.jvpp.VppCallbackException reply) {
-
- io.fd.vpp.jvpp.callback.JVppCallback failedCall;
- synchronized(requests) {
- failedCall = requests.remove(reply.getCtxId());
- }
-
- if(failedCall != null) {
- try {
- failedCall.onError(reply);
- } catch(RuntimeException ex) {
- ex.addSuppressed(reply);
- LOG.log(java.util.logging.Level.WARNING, java.lang.String.format("Callback: %s failed while handling exception: %s", failedCall, reply), ex);
- }
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void onControlPingReply(final io.fd.vpp.jvpp.dto.ControlPingReply reply) {
-
- io.fd.vpp.jvpp.callback.ControlPingCallback callback;
- final int replyId = reply.context;
- synchronized(requests) {
- callback = (io.fd.vpp.jvpp.callback.ControlPingCallback) requests.remove(replyId);
- }
-
- if(callback != null) {
- callback.onControlPingReply(reply);
- }
- }
-
-$methods
-}
-""")
-
-
-def _generate_callback_methods(model):
- plugin_package = model.plugin_package
- methods = []
- for msg in model.messages:
- if is_dump(msg) or is_request(msg):
- continue
- if is_control_ping_reply(msg):
- # Skip control ping managed by jvpp registry.
- continue
-
- # Generate callbacks for all messages except for dumps and requests (handled by vpp, not client).
- template = _CALLBACK_METHOD_TEMPLATE
- if is_event(msg):
- template = _CALLBACK_EVENT_METHOD_TEMPLATE
- msg_name = msg.java_name_upper
- methods.append(template.substitute(
- message=msg_name,
- callback="%sCallback" % msg_name,
- plugin_package=plugin_package
- ))
- return "\n".join(methods)
-
-_CALLBACK_METHOD_TEMPLATE = Template("""
- @Override
- @SuppressWarnings("unchecked")
- public void on${message}(final $plugin_package.dto.${message} reply) {
-
- $plugin_package.callback.$callback callback;
- final int replyId = reply.context;
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received ${message} event message: %s", reply));
- }
- synchronized(requests) {
- callback = ($plugin_package.callback.$callback) requests.remove(replyId);
- }
-
- if(callback != null) {
- callback.on${message}(reply);
- }
- }
-""")
-
-_CALLBACK_EVENT_METHOD_TEMPLATE = Template("""
- @Override
- @SuppressWarnings("unchecked")
- public void on${message}($plugin_package.dto.${message} notification) {
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received ${message} event message: %s", notification));
- }
- eventCallback.on${message}(notification);
- }
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_common_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_common_gen.py
deleted file mode 100755
index 499adbc3f56..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_common_gen.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_model import is_array
-
-
-def generate_fields(fields, access_modifier="public"):
- return "\n".join(_FIELD_TEMPLATE
- .substitute(access_modifier=access_modifier, type=f.type.java_name_fqn, name=f.java_name)
- for f in fields)
-
-_FIELD_TEMPLATE = Template(""" ${access_modifier} ${type} ${name};""")
-
-
-def generate_hash_code(fields):
- if len(fields) == 1 and is_array(fields[0]):
- return _HASH_CODE_SINGLE_ARRAY_TEMPLATE.substitute(array_field=fields[0].java_name)
- return _HASH_CODE_TEMPLATE.substitute(fields=", ".join(f.java_name for f in fields))
-
-_HASH_CODE_TEMPLATE = Template("""
- @Override
- @io.fd.vpp.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD")
- public int hashCode() {
- return java.util.Objects.hash($fields);
- }""")
-
-_HASH_CODE_SINGLE_ARRAY_TEMPLATE = Template("""
- @Override
- @io.fd.vpp.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD")
- public int hashCode() {
- return java.util.Arrays.hashCode($array_field);
- }""")
-
-
-def generate_equals(class_name, fields):
- comparisons = []
- for f in fields:
- if is_array(f):
- comparisons.append(_EQUALS_ARRAY_FIELD_TEMPLATE.substitute(field_name=f.java_name))
- else:
- comparisons.append(_EQUALS_FIELD_TEMPLATE.substitute(field_name=f.java_name))
-
- if comparisons:
- comparisons.insert(0, _EQUALS_OTHER_TEMPLATE.substitute(cls_name=class_name))
- return _EQUALS_TEMPLATE.substitute(comparisons="\n".join(comparisons))
-
-_EQUALS_TEMPLATE = Template("""
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-$comparisons
-
- return true;
- }""")
-
-_EQUALS_OTHER_TEMPLATE = Template("""
- final $cls_name other = ($cls_name) o;
-""")
-
-_EQUALS_FIELD_TEMPLATE = Template(""" if (!java.util.Objects.equals(this.$field_name, other.$field_name)) {
- return false;
- }""")
-
-_EQUALS_ARRAY_FIELD_TEMPLATE = Template(""" if (!java.util.Arrays.equals(this.$field_name, other.$field_name)) {
- return false;
- }""")
-
-
-def generate_to_string(class_name, fields):
- to_string = []
- for f in fields:
- if is_array(f):
- to_string.append(_TO_STRING_ARRAY_FIELD_TEMPLATE.substitute(field_name=f.java_name))
- else:
- to_string.append(_TO_STRING_FIELD_TEMPLATE.substitute(field_name=f.java_name))
-
- to_string_fields = " \"}\";"
- if to_string:
- to_string_fields = " + \", \" +\n".join(to_string) + " + \"}\";"
-
- return _TO_STRING_TEMPLATE.substitute(
- class_name=class_name,
- to_string_fields=to_string_fields
- )
-
-_TO_STRING_TEMPLATE = Template("""
- @Override
- public java.lang.String toString() {
- return "$class_name{" +
-$to_string_fields
- }""")
-
-_TO_STRING_FIELD_TEMPLATE = Template(""" \"$field_name=\" + $field_name""")
-
-_TO_STRING_ARRAY_FIELD_TEMPLATE = Template(
- """ \"$field_name=\" + java.util.Arrays.toString($field_name)""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py
deleted file mode 100644
index 3da367a4d5f..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_model import is_control_ping, is_control_ping_reply, is_dump, is_request, is_details, is_reply, is_event
-
-
-def generate_future_facade(work_dir, model, logger):
- logger.debug("Generating JVpp future facade for %s" % model.json_api_files)
- _generate_future_jvpp(work_dir, model),
- _generate_future_jvpp_facade(work_dir, model)
- _generate_future_jvpp_callback(work_dir, model)
-
-
-def _generate_future_jvpp(work_dir, model):
- with open("%s/FutureJVpp%s.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_FUTURE_JVPP_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_future_jvpp_methods(model)
- ))
-
-_FUTURE_JVPP_TEMPLATE = Template('''
-package $plugin_package.future;
-
-/**
- * <p>Async facade extension adding specific methods for each request invocation
- * <br>It was generated by jvpp_future_facade_gen.py based on $json_filename.
- */
-public interface FutureJVpp${plugin_name} extends io.fd.vpp.jvpp.future.FutureJVppInvoker {
-$methods
-
- @Override
- public $plugin_package.notification.${plugin_name}EventRegistry getEventRegistry();
-
-}
-''')
-
-
-def _generate_future_jvpp_methods(model):
- methods = []
- for msg in model.messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- reply_name = None
- if is_request(msg):
- reply_name = msg.reply_java
- elif is_dump(msg):
- # use reply dump wrappers
- reply_name = "%sReplyDump" % msg.reply_java
- else:
- continue
-
- methods.append(_FUTURE_JVPP_METHOD_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- method_name=msg.java_name_lower,
- reply_name=reply_name,
- request_name=msg.java_name_upper
- ))
- return "".join(methods)
-
-_FUTURE_JVPP_METHOD_TEMPLATE = Template('''
- java.util.concurrent.CompletionStage<${plugin_package}.dto.${reply_name}> ${method_name}(${plugin_package}.dto.${request_name} request);
-''')
-
-
-def _generate_future_jvpp_facade(work_dir, model):
- with open("%s/FutureJVpp%sFacade.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_FUTURE_JVPP_FACADE_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_future_jvpp_facade_methods(model)
- ))
-
-_FUTURE_JVPP_FACADE_TEMPLATE = Template('''
-package $plugin_package.future;
-
-/**
- * <p>Implementation of FutureJVpp based on AbstractFutureJVppInvoker
- * <br>It was generated by jvpp_future_facade_gen.py based on $json_filename.
- */
-public class FutureJVpp${plugin_name}Facade extends io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker implements FutureJVpp${plugin_name} {
-
- private final $plugin_package.notification.${plugin_name}EventRegistryImpl eventRegistry = new $plugin_package.notification.${plugin_name}EventRegistryImpl();
-
- /**
- * <p>Create FutureJVpp${plugin_name}Facade object for provided JVpp instance.
- * Constructor internally creates FutureJVppFacadeCallback class for processing callbacks
- * and then connects to provided JVpp instance
- *
- * @param jvpp provided io.fd.vpp.jvpp.JVpp instance
- *
- * @throws java.io.IOException in case instance cannot connect to JVPP
- */
- public FutureJVpp${plugin_name}Facade(final io.fd.vpp.jvpp.JVppRegistry registry, final io.fd.vpp.jvpp.JVpp jvpp) throws java.io.IOException {
- super(jvpp, registry, new java.util.HashMap<>());
- java.util.Objects.requireNonNull(registry, "JVppRegistry should not be null");
- registry.register(jvpp, new FutureJVpp${plugin_name}FacadeCallback(getRequests(), eventRegistry));
- }
-
- @Override
- public $plugin_package.notification.${plugin_name}EventRegistry getEventRegistry() {
- return eventRegistry;
- }
-
-$methods
-}
-''')
-
-
-def _generate_future_jvpp_facade_methods(model):
- methods = []
- for msg in model.messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- template = None
- if is_request(msg):
- template = _FUTURE_JVPP_FACADE_REQUEST_TEMPLATE
- elif is_dump(msg):
- template = _FUTURE_JVPP_FACADE_DUMP_TEMPLATE
- else:
- continue
-
- methods.append(template.substitute(
- plugin_package=model.plugin_package,
- method_name=msg.java_name_lower,
- reply_name=msg.reply_java,
- request_name=msg.java_name_upper
- ))
- return "".join(methods)
-
-_FUTURE_JVPP_FACADE_REQUEST_TEMPLATE = Template('''
- @Override
- public java.util.concurrent.CompletionStage<${plugin_package}.dto.${reply_name}> ${method_name}(${plugin_package}.dto.${request_name} request) {
- return send(request);
- }
-''')
-
-_FUTURE_JVPP_FACADE_DUMP_TEMPLATE = Template('''
- @Override
- public java.util.concurrent.CompletionStage<${plugin_package}.dto.${reply_name}ReplyDump> ${method_name}(${plugin_package}.dto.${request_name} request) {
- return send(request, new ${plugin_package}.dto.${reply_name}ReplyDump());
- }
-''')
-
-
-def _generate_future_jvpp_callback(work_dir, model):
- with open("%s/FutureJVpp%sFacadeCallback.java" % (work_dir, model.plugin_java_name), "w") as f:
- f.write(_FUTURE_JVPP_CALLBACK_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- methods=_generate_future_jvpp_callback_methods(model)
- ))
-
-_FUTURE_JVPP_CALLBACK_TEMPLATE = Template("""
-package $plugin_package.future;
-
-/**
- * <p>Async facade callback setting values to future objects
- * <br>It was generated by jvpp_future_facade_gen.py based on $json_filename.
- */
-public final class FutureJVpp${plugin_name}FacadeCallback implements $plugin_package.callback.JVpp${plugin_name}GlobalCallback {
-
- private final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends io.fd.vpp.jvpp.dto.JVppReply<?>>> requests;
- private final $plugin_package.notification.Global${plugin_name}EventCallback notificationCallback;
- private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(FutureJVpp${plugin_name}FacadeCallback.class.getName());
-
- public FutureJVpp${plugin_name}FacadeCallback(
- final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends io.fd.vpp.jvpp.dto.JVppReply<?>>> requestMap,
- final $plugin_package.notification.Global${plugin_name}EventCallback notificationCallback) {
- this.requests = requestMap;
- this.notificationCallback = notificationCallback;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void onError(io.fd.vpp.jvpp.VppCallbackException reply) {
- final java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<?>> completableFuture;
-
- synchronized(requests) {
- completableFuture = (java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<?>>) requests.get(reply.getCtxId());
- }
-
- if(completableFuture != null) {
- completableFuture.completeExceptionally(reply);
-
- synchronized(requests) {
- requests.remove(reply.getCtxId());
- }
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void onControlPingReply(final io.fd.vpp.jvpp.dto.ControlPingReply reply) {
- java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<?>> completableFuture;
-
- final int replyId = reply.context;
- synchronized(requests) {
- completableFuture = (java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<?>>) requests.get(replyId);
-
- if(completableFuture != null) {
- // Finish dump call
- if (completableFuture instanceof io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture) {
- completableFuture.complete(((io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture) completableFuture).getReplyDump());
- // Remove future mapped to dump call context id
- requests.remove(((io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture) completableFuture).getContextId());
- } else {
- // reply to regular control ping, complete the future
- completableFuture.complete(reply);
- }
- requests.remove(replyId);
- } else {
- // future not yet created by writer, create new future, complete it and put to map under ping id
- completableFuture = new java.util.concurrent.CompletableFuture<>();
- completableFuture.complete(reply);
- requests.put(replyId, completableFuture);
- }
- }
- }
-
-$methods
-}
-""")
-
-
-def _generate_future_jvpp_callback_methods(model):
- methods = []
- for msg in model.messages:
- if is_control_ping(msg) or is_control_ping_reply(msg):
- # Skip control_ping managed by jvpp registry.
- continue
- if is_dump(msg) or is_request(msg):
- continue
-
- # Generate callbacks for all messages except for dumps and requests (handled by vpp, not client).
- template = None
- request_dto = None
- if is_details(msg):
- template = _FUTURE_JVPP_FACADE_DETAILS_CALLBACK_TEMPLATE
- request_dto = msg.request_java
- elif is_reply(msg):
- template = _FUTURE_JVPP_FACADE_REPLY_CALLBACK_TEMPLATE
- request_dto = msg.request_java
- elif is_event(msg):
- template = _FUTURE_JVPP_FACADE_EVENT_CALLBACK_TEMPLATE
- else:
- raise TypeError("Unknown message type %s", msg)
-
- methods.append(template.substitute(
- plugin_package=model.plugin_package,
- callback_dto=msg.java_name_upper,
- request_dto=request_dto,
- callback_dto_field=msg.java_name_lower,
- ))
- return "".join(methods)
-
-
-_FUTURE_JVPP_FACADE_DETAILS_CALLBACK_TEMPLATE = Template("""
- @Override
- @SuppressWarnings("unchecked")
- public void on$callback_dto(final $plugin_package.dto.$callback_dto reply) {
- io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture<$plugin_package.dto.${callback_dto}ReplyDump> completableFuture;
- final int replyId = reply.context;
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received $callback_dto event message: %s", reply));
- }
- synchronized(requests) {
- completableFuture = (io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture<$plugin_package.dto.${callback_dto}ReplyDump>) requests.get(replyId);
-
- if(completableFuture == null) {
- // reply received before writer created future,
- // create new future, and put into map to notify sender that reply is already received,
- // following details replies will add information to this future
- completableFuture = new io.fd.vpp.jvpp.future.AbstractFutureJVppInvoker.CompletableDumpFuture<>(replyId,
- new $plugin_package.dto.${callback_dto}ReplyDump());
- requests.put(replyId, completableFuture);
- }
- completableFuture.getReplyDump().$callback_dto_field.add(reply);
- }
- }
-""")
-
-_FUTURE_JVPP_FACADE_REPLY_CALLBACK_TEMPLATE = Template("""
- @Override
- @SuppressWarnings("unchecked")
- public void on$callback_dto(final $plugin_package.dto.$callback_dto reply) {
- java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<$plugin_package.dto.$request_dto>> completableFuture;
- final int replyId = reply.context;
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received $callback_dto event message: %s", reply));
- }
- synchronized(requests) {
- completableFuture =
- (java.util.concurrent.CompletableFuture<io.fd.vpp.jvpp.dto.JVppReply<$plugin_package.dto.$request_dto>>) requests.get(replyId);
-
- if(completableFuture != null) {
- // received reply on request, complete future created by sender and remove it from map
- completableFuture.complete(reply);
- requests.remove(replyId);
- } else {
- // reply received before writer created future,
- // create new future, complete it and put into map to
- // notify sender that reply is already received
- completableFuture = new java.util.concurrent.CompletableFuture<>();
- completableFuture.complete(reply);
- requests.put(replyId, completableFuture);
- }
- }
- }
-""")
-
-_FUTURE_JVPP_FACADE_EVENT_CALLBACK_TEMPLATE = Template("""
- @Override
- public void on$callback_dto($plugin_package.dto.$callback_dto notification) {
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received $callback_dto event message: %s", notification));
- }
- notificationCallback.on$callback_dto(notification);
- }
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_ifc_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_ifc_gen.py
deleted file mode 100755
index e2b2922ed20..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_ifc_gen.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jvpp_model import is_request, is_dump, is_event
-
-
-def generate_java_ifc(work_dir, model, logger):
- logger.debug("Generating JVpp interface for %s" % model.json_api_files)
- messages = filter(_jvpp_ifc_filter, model.messages)
- plugin_package = model.plugin_package
- methods = []
- for msg in messages:
- if msg.has_fields:
- methods.append(_JVPP_IFC_METHOD_TEMPLATE.substitute(
- name=msg.java_name_lower,
- plugin_package=plugin_package,
- type=msg.java_name_upper))
- else:
- methods.append(_JVPP_IFC_NO_ARG_METHOD_TEMPLATE.substitute(name=msg.java_name_lower))
-
- plugin_name = model.plugin_java_name
- jvpp_interface = _JVPP_IFC_TEMPLATE.substitute(
- plugin_package=plugin_package,
- json_filename=model.json_api_files,
- plugin_name=plugin_name,
- methods="\n".join(methods)
- )
- with open("%s/JVpp%s.java" % (work_dir, plugin_name), "w") as f:
- f.write(jvpp_interface)
-
-
-def _jvpp_ifc_filter(msg):
- return is_request(msg) or is_dump(msg) or is_event(msg)
-
-
-_JVPP_IFC_METHOD_TEMPLATE = Template(
- """ int $name($plugin_package.dto.$type request) throws io.fd.vpp.jvpp.VppInvocationException;""")
-
-_JVPP_IFC_NO_ARG_METHOD_TEMPLATE = Template(""" int $name() throws io.fd.vpp.jvpp.VppInvocationException;""")
-
-_JVPP_IFC_TEMPLATE = Template("""package $plugin_package;
-
-/**
- * <p>Java representation of plugin's api file.
- * <br>It was generated by jvpp_impl_gen.py based on $json_filename.
- * <br>(python representation of api file generated by vppapigen)
- */
-public interface JVpp${plugin_name} extends io.fd.vpp.jvpp.JVpp {
- /**
- * Generic dispatch method for sending requests to VPP
- *
- * @throws io.fd.vpp.jvpp.VppInvocationException if send request had failed
- */
- int send(io.fd.vpp.jvpp.dto.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException;
-$methods
-}
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_impl_gen.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_impl_gen.py
deleted file mode 100755
index 376952b620e..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_impl_gen.py
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from string import Template
-
-from jvpp_model import is_request, is_dump, is_event
-
-
-def generate_java_impl(work_dir, model, logger):
- logger.debug("Generating JVpp implementation for %s" % model.json_api_files)
- messages = filter(_jvpp_impl_filter, model.messages)
- plugin_package = model.plugin_package
- methods = []
- for msg in messages:
- if msg.has_fields:
- methods.append(_JVPP_IMPL_METHOD_TEMPLATE.substitute(
- name=msg.java_name_lower,
- plugin_package=plugin_package,
- type=msg.java_name_upper))
- else:
- methods.append(_JVPP_IMPL_NO_ARG_METHOD_TEMPLATE.substitute(
- name=msg.java_name_lower,
- type=msg.java_name_upper))
-
- plugin_name = model.plugin_java_name
- jvpp_impl = _JVPP_IMPL_TEMPLATE.substitute(
- plugin_package=plugin_package,
- json_filename=model.json_api_files,
- plugin_name=model.plugin_java_name,
- plugin_name_underscore=model.plugin_name,
- methods="\n".join(methods))
-
- with open("%s/JVpp%sImpl.java" % (work_dir, plugin_name), "w") as f:
- f.write(jvpp_impl)
-
-
-def _jvpp_impl_filter(msg):
- return is_request(msg) or is_dump(msg) or is_event(msg)
-
-
-_JVPP_IMPL_TEMPLATE = Template("""package $plugin_package;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.PosixFilePermissions;
-import java.util.Set;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-import io.fd.vpp.jvpp.callback.JVppCallback;
-import io.fd.vpp.jvpp.VppConnection;
-import io.fd.vpp.jvpp.JVppRegistry;
-
-/**
- * <p>Default implementation of JVpp interface.
- * <br>It was generated by jvpp_impl_gen.py based on $json_filename.
- * <br>(python representation of api file generated by vppapigen)
- */
-public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} {
-
- private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName());
- private static final java.lang.String LIBNAME = "libjvpp_${plugin_name_underscore}.so";
-
- // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply).
- static {
- try {
- loadLibrary();
- } catch (Exception e) {
- LOG.severe("Can't find jvpp jni library: " + LIBNAME);
- throw new ExceptionInInitializerError(e);
- }
- }
-
- private static void loadStream(final InputStream is) throws IOException {
- final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
- final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
- try {
- Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
-
- try {
- Runtime.getRuntime().load(p.toString());
- } catch (UnsatisfiedLinkError e) {
- throw new IOException("Failed to load library " + p, e);
- }
- } finally {
- try {
- Files.deleteIfExists(p);
- } catch (IOException e) {
- }
- }
- }
-
- private static void loadLibrary() throws IOException {
- try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) {
- if (is == null) {
- throw new IOException("Failed to open library resource " + LIBNAME);
- }
- loadStream(is);
- }
- }
-
- private VppConnection connection;
- private JVppRegistry registry;
-
- private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex);
- @Override
- public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) {
- this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null");
- this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null");
- connection.checkActive();
- init0(callback, queueAddress, clientIndex);
- }
-
- private static native void close0();
- @Override
- public void close() {
- close0();
- }
-
- @Override
- public int send(io.fd.vpp.jvpp.dto.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException {
- return request.send(this);
- }
-
- @Override
- public final int controlPing(final io.fd.vpp.jvpp.dto.ControlPing controlPing) throws io.fd.vpp.jvpp.VppInvocationException {
- return registry.controlPing(JVpp${plugin_name}Impl.class);
- }
-$methods
-}
-""")
-
-_JVPP_IMPL_METHOD_TEMPLATE = Template("""
- private static native int ${name}0($plugin_package.dto.$type request);
- public final int $name($plugin_package.dto.$type request) throws io.fd.vpp.jvpp.VppInvocationException {
- java.util.Objects.requireNonNull(request, "Null request object");
- connection.checkActive();
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine(java.lang.String.format("Sending $type event message: %s", request));
- }
- int result=${name}0(request);
- if (result<0){
- throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);
- }
- return result;
- }""")
-
-_JVPP_IMPL_NO_ARG_METHOD_TEMPLATE = Template("""
- private static native int ${name}0() throws io.fd.vpp.jvpp.VppInvocationException;
- public final int $name() throws io.fd.vpp.jvpp.VppInvocationException {
- connection.checkActive();
- LOG.fine("Sending $type event message");
- int result=${name}0();
- if(result<0){
- throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);
- }
- return result;
- }""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/jvpp_model.py b/extras/japi/java/jvpp/gen/jvppgen/jvpp_model.py
deleted file mode 100755
index 9a3204e3fc6..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/jvpp_model.py
+++ /dev/null
@@ -1,624 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-import json
-import pprint
-from collections import OrderedDict
-
-import binascii
-
-BASE_PACKAGE = "io.fd.vpp.jvpp"
-
-
-class ParseException(Exception):
- pass
-
-
-class Type(object):
- def __init__(self, name, java_name, java_name_fqn, jni_signature, jni_type, jni_accessor,
- host_to_net_function, net_to_host_function):
- """
- Initializes Type class.
-
- :param name: name of type as defined in .api file, e.g. u8, u32[] or mac_entry
- :param java_name: corresponding java name, e.g. byte, int[] or MacEntry
- :param java_name_fqn: fully qualified java name, e.g. io.fd.vpp.jvpp.core.types.MacEntry
- :param jni_signature: JNI Type signature, e.g. B, [I or Lio.fd.vpp.jvpp.core.types.MacEntry;
- See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#type_signatures
- :param jni_type: JNI reference type, e.g. jbyte jintArray, jobject
- See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#reference_types
- :param jni_accessor: Java type do by used in Get<type>Field, Set<type>Field and other functions.
- See https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#accessing_fields_of_objects
- :param host_to_net_function: name of function host to net byte order swap function
- :param net_to_host_function: name of function net to host byte order swap function
- """
- self.name = name
- self.java_name = java_name
-
- # Java generation specific properties, TODO(VPP-1186): move to Java specific subclass
- self.java_name_fqn = java_name_fqn
-
- # JNI generation specific properties, TODO(VPP-1186): move to JNI specific subclass
- self.jni_signature = jni_signature
-
- # Native type, see:
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#primitive_types
- # and
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#reference_types
- self.jni_type = jni_type
-
- # Java type do by used in Get<type>Field, Set<type>Field and other functions, see:
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#accessing_fields_of_objects
- self.jni_accessor = jni_accessor
-
- self.host_to_net_function = host_to_net_function
- self.net_to_host_function = net_to_host_function
- self.is_swap_needed = host_to_net_function and net_to_host_function
-
-
-class SimpleType(Type):
- def __init__(self, name, java_name, jni_signature, jni_type, jni_accessor,
- host_to_net_function=None, net_to_host_function=None):
- super(SimpleType, self).__init__(
- name=name,
- java_name=java_name,
- java_name_fqn=java_name,
- jni_signature=jni_signature,
- jni_type=jni_type,
- jni_accessor=jni_accessor,
- host_to_net_function=host_to_net_function,
- net_to_host_function=net_to_host_function
- )
- self.vpp_name = name
-
- def get_host_to_net_function(self, host_ref_name, net_ref_name):
- return "%s = %s(%s)" % (net_ref_name, self.host_to_net_function, host_ref_name)
-
- def __str__(self):
- return "SimpleType{name:%s, java_name:%s}" % (self.name, self.java_name)
-
-
-# TODO(VPP-1187): add array host to net functions to reduce number of members and simplify JNI generation
-class Array(Type):
- def __init__(self, base_type, name=None):
- if name is None:
- name = base_type.name + _ARRAY_SUFFIX
- super(Array, self).__init__(
- name=name,
- java_name=base_type.java_name + _ARRAY_SUFFIX,
- java_name_fqn=base_type.java_name_fqn + _ARRAY_SUFFIX,
- jni_signature="[%s" % base_type.jni_signature,
- jni_type="%sArray" % base_type.jni_type,
- jni_accessor="Object",
- host_to_net_function=base_type.host_to_net_function,
- net_to_host_function=base_type.net_to_host_function
- )
- self.base_type = base_type
-
- def get_host_to_net_function(self, host_ref_name, net_ref_name):
- return self.base_type.get_host_to_net_function(host_ref_name, net_ref_name)
-
- def __str__(self):
- return "Array{name:%s, java_name:%s}" % (self.name, self.java_name)
-
-
-class Enum(Type):
- def __init__(self, name, value, constants, definition, plugin_name):
- _java_name = _underscore_to_camelcase_upper(name)
-
- super(Enum, self).__init__(
- name=name,
- java_name=_java_name,
- java_name_fqn="io.fd.vpp.jvpp.%s.types.%s" % (plugin_name, _java_name),
- jni_signature="Lio/fd/vpp/jvpp/%s/types/%s;" % (plugin_name, _java_name),
- jni_type="jobject",
- jni_accessor="Object",
- host_to_net_function="_host_to_net_%s" % name,
- net_to_host_function="_net_to_host_%s" % name
- )
-
- self.value = value
- self.constants = constants
- self.doc = _message_to_javadoc(definition)
- self.java_name_lower = _underscore_to_camelcase_lower(name)
- self.vpp_name = "%s%s%s" % (_VPP_TYPE_PREFIX, name, _VPP_TYPE_SUFFIX)
- # Fully qualified class name used by FindClass function, see:
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass
- self.jni_name = "io/fd/vpp/jvpp/%s/types/%s" % (plugin_name, _java_name)
-
- def get_host_to_net_function(self, host_ref_name, net_ref_name):
- return "_host_to_net_%s(env, %s, &(%s))" % (self.name, host_ref_name, net_ref_name)
-
-
-class Class(Type):
- def __init__(self, name, crc, fields, definition, plugin_name):
- _java_name = _underscore_to_camelcase_upper(name)
-
- super(Class, self).__init__(
- name=name,
- java_name=_java_name,
- java_name_fqn="io.fd.vpp.jvpp.%s.types.%s" % (plugin_name, _java_name),
- jni_signature="Lio/fd/vpp/jvpp/%s/types/%s;" % (plugin_name, _java_name),
- jni_type="jobject",
- jni_accessor="Object",
- host_to_net_function="_host_to_net_%s" % name,
- net_to_host_function="_net_to_host_%s" % name
- )
-
- self.crc = crc
- self.fields = fields
- self.doc = _message_to_javadoc(definition)
- self.java_name_lower = _underscore_to_camelcase_lower(name)
- self.vpp_name = "%s%s%s" % (_VPP_TYPE_PREFIX, name, _VPP_TYPE_SUFFIX)
- # Fully qualified class name used by FindClass function, see:
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass
- self.jni_name = "io/fd/vpp/jvpp/%s/types/%s" % (plugin_name, _java_name)
-
- def get_host_to_net_function(self, host_ref_name, net_ref_name):
- return "_host_to_net_%s(env, %s, &(%s))" % (self.name, host_ref_name, net_ref_name)
-
-
-class Union(Type):
- def __init__(self, name, crc, fields, definition, plugin_name):
- _java_name = _underscore_to_camelcase_upper(name)
-
- super(Union, self).__init__(
- name=name,
- java_name=_java_name,
- java_name_fqn="io.fd.vpp.jvpp.%s.types.%s" % (plugin_name, _java_name),
- jni_signature="Lio/fd/vpp/jvpp/%s/types/%s;" % (plugin_name, _java_name),
- jni_type="jobject",
- jni_accessor="Object",
- host_to_net_function="_host_to_net_%s" % name,
- net_to_host_function="_net_to_host_%s" % name
- )
-
- self.crc = crc
- self.fields = fields
- self.doc = _message_to_javadoc(definition)
- self.java_name_lower = _underscore_to_camelcase_lower(name)
- self.vpp_name = "%s%s%s" % (_VPP_TYPE_PREFIX, name, _VPP_TYPE_SUFFIX)
- # Fully qualified class name used by FindClass function, see:
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#FindClass
- self.jni_name = "io/fd/vpp/jvpp/%s/types/%s" % (plugin_name, _java_name)
-
- def get_host_to_net_function(self, host_ref_name, net_ref_name):
- return "_host_to_net_%s(env, %s, &(%s))" % (self.name, host_ref_name, net_ref_name)
-
-
-class Field(object):
- def __init__(self, name, field_type, array_len=None, array_len_field=None):
- self.name = name
- self.java_name = _underscore_to_camelcase_lower(name)
- self.java_name_upper = _underscore_to_camelcase_upper(name)
- self.type = field_type
- self.array_len = array_len
- self.array_len_field = array_len_field
-
- def __str__(self):
- return "Field{name:%s, java_name:%s, type:%s}" % (self.name, self.java_name, self.type)
-
-
-class Message(object):
- def __init__(self, name, crc, fields, definition):
- self.name = name
- self.java_name_upper = _underscore_to_camelcase_upper(name)
- self.java_name_lower = _underscore_to_camelcase_lower(name)
- self.crc = crc[2:]
- self.fields = fields
- self.has_fields = fields != []
- self.doc = _message_to_javadoc(definition)
-
- def __str__(self):
- return "Message{name:%s, java_name:%s, crc:%s, fields:%s}" % (
- self.name, self.java_name_upper, self.crc, self.fields)
-
-
-class Event(Message):
- def __init__(self, name, crc, fields, definition):
- super(Event, self).__init__(name, crc, fields, definition)
-
-
-class Request(Message):
- def __init__(self, name, reply, crc, fields, definition):
- super(Request, self).__init__(name, crc, fields, definition)
- self.reply = reply
- self.reply_java = _underscore_to_camelcase_upper(reply)
-
- def __str__(self):
- return "Request{name:%s, reply:%s, crc:%s, fields:%s}" % (self.name, self.reply, self.crc, self.fields)
-
-
-class Reply(Message):
- def __init__(self, name, request, crc, fields, definition):
- super(Reply, self).__init__(name, crc, fields, definition)
- self.request = request
- self.request_java = _underscore_to_camelcase_upper(request)
-
- def __str__(self):
- return "Reply{name:%s, request:%s, crc:%s, fields:%s}" % (self.name, self.request, self.crc, self.fields)
-
-
-class Dump(Message):
- def __init__(self, name, details, crc, fields, definition):
- super(Dump, self).__init__(name, crc, fields, definition)
- self.details = details
- self.reply_java = _underscore_to_camelcase_upper(details)
-
- def __str__(self):
- return "Dump{name:%s, details:%s, crc:%s, fields:%s}" % (self.name, self.details, self.crc, self.fields)
-
-
-class Details(Message):
- def __init__(self, name, dump, crc, fields, definition):
- super(Details, self).__init__(name, crc, fields, definition)
- self.dump = dump
- self.request_java = _underscore_to_camelcase_upper(dump)
-
- def __str__(self):
- return "Details{name:%s, dump:%s, crc:%s, fields:%s}" % (self.name, self.dump, self.crc, self.fields)
-
-
-def is_retval(field):
- return field.name == u'retval'
-
-
-def is_array(field):
- return field.array_len is not None
-
-
-def is_request(msg):
- return hasattr(msg, 'reply')
-
-
-def is_reply(msg):
- return hasattr(msg, 'request')
-
-
-def is_dump(msg):
- return hasattr(msg, 'details')
-
-
-def is_details(msg):
- return hasattr(msg, 'dump')
-
-
-def is_event(msg):
- return isinstance(msg, Event)
-
-
-def is_control_ping(msg):
- return msg.name == u'control_ping'
-
-
-def is_control_ping_reply(msg):
- return msg.name == u'control_ping_reply'
-
-
-def crc(block):
- s = str(block).encode()
- return binascii.crc32(s) & 0xffffffff
-
-
-class JVppModel(object):
- def __init__(self, logger, json_api_files, plugin_name):
- self.logger = logger
- # TODO(VPP-1188): provide json_file_by_definition map to improve javadoc
- self.json_api_files = json_api_files
- self.plugin_package = BASE_PACKAGE + "." + plugin_name
- self.plugin_name = plugin_name
- self.plugin_java_name = _underscore_to_camelcase_upper(plugin_name)
- self._load_json_files(json_api_files)
- self._parse_services()
- self._parse_messages()
- self._validate_messages()
-
- def _load_json_files(self, json_api_files):
- types = {}
- self._messages = []
- self._services = {}
- self._aliases = {}
- for file_name in json_api_files:
- with open(file_name) as f:
- j = json.load(f)
- types.update({d[0]: {'type': 'enum', 'data': d} for d in j['enums']})
- types.update({d[0]: {'type': 'type', 'data': d} for d in j['types']})
- types.update({d[0]: {'type': 'union', 'data': d} for d in j['unions']})
- self._messages.extend(j['messages'])
- self._services.update(j['services'])
- self._aliases.update(j['aliases'])
-
- self._parse_types(types)
-
- def _parse_aliases(self, types):
-
- # model aliases
- for alias_name in self._aliases:
- alias = self._aliases[alias_name]
- alias_type = {"type": "type"}
- java_name_lower = _underscore_to_camelcase_lower(alias_name)
- vpp_type = alias["type"]
- crc_value = '0x%08x' % crc(alias_name)
- if "length" in alias:
- length = alias["length"]
- alias_type["data"] = [
- alias_name,
- [
- vpp_type,
- java_name_lower,
- length
- ],
- {
- "crc": crc_value
- }
- ]
- else:
- alias_type["data"] = [
- alias_name,
- [
- vpp_type,
- java_name_lower
- ],
- {
- "crc": crc_value
- }
- ]
-
- types[alias_name] = alias_type
-
- def _parse_types(self, types):
- self._parse_simple_types()
- self._parse_aliases(types)
- i = 0
- while True:
- unresolved = {}
- for name, value in types.items():
- if name in self._types_by_name:
- continue
-
- type = value['type']
- data = value['data'][1:]
- try:
- if type == 'enum':
- type = self._parse_enum(name, data)
- elif type == 'union':
- type = self._parse_union(name, data)
- elif type == 'type':
- type = self._parse_type(name, data)
- else:
- self.logger.warning("Unsupported type %s. Ignoring...", type)
- continue
-
- self._types_by_name[name] = type
- self._types_by_name[name + _ARRAY_SUFFIX] = Array(type)
- except ParseException as e:
- self.logger.debug("Failed to parse %s type in iteration %s: %s.", name, i, e)
- unresolved[name] = value
- if len(unresolved) == 0:
- break
- if i > 3:
- raise ParseException('Unresolved type definitions {}'
- .format(unresolved))
- types = unresolved
- i += 1
-
- self.types = self._types_by_name.values()
-
- def _parse_simple_types(self):
- # Mapping according to:
- # http://docs.oracle.com/javase/7/do+'[]'cs/technotes/guides/jni/spec/types.html
- # and
- # https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines
- #
- # Unsigned types are converted to signed java types that have the same size.
- # It is the API user responsibility to interpret them correctly.
-
- self._types_by_name = OrderedDict({
- 'u8': SimpleType('u8', 'byte', 'B', 'jbyte', 'Byte'),
- 'i8': SimpleType('i8', 'byte', 'B', 'jbyte', 'Byte'),
- 'u16': SimpleType('u16', 'short', 'S', 'jshort', 'Short',
- host_to_net_function='clib_host_to_net_u16',
- net_to_host_function='clib_net_to_host_u16'),
- 'i16': SimpleType('i16', 'short', 'S', 'jshort', 'Short',
- host_to_net_function='clib_host_to_net_i16',
- net_to_host_function='clib_net_to_host_i16'),
- 'u32': SimpleType('u32', 'int', 'I', 'jint', 'Int',
- host_to_net_function='clib_host_to_net_u32',
- net_to_host_function='clib_net_to_host_u32'),
- 'i32': SimpleType('i32', 'int', 'I', 'jint', 'Int',
- host_to_net_function='clib_host_to_net_i32',
- net_to_host_function='clib_net_to_host_i32'),
- 'u64': SimpleType('u64', 'long', 'J', 'jlong', 'Long',
- host_to_net_function='clib_host_to_net_u64',
- net_to_host_function='clib_net_to_host_u64'),
- 'i64': SimpleType('i64', 'long', 'J', 'jlong', 'Long',
- host_to_net_function='clib_host_to_net_i64',
- net_to_host_function='clib_net_to_host_i64'),
- 'f64': SimpleType('f64', 'double', 'D', 'jdouble', 'Double'),
- 'string': SimpleType('string', 'String', 'Ljava/lang/String;', 'jstring', 'Object',
- host_to_net_function='_host_to_net_string',
- net_to_host_function='_net_to_host_string')
- })
-
- for n, t in self._types_by_name.items():
- self._types_by_name[n + _ARRAY_SUFFIX] = Array(t)
-
- def _parse_enum(self, name, definition):
- self.logger.debug("Parsing enum %s: %s", name, definition)
- constants = []
- type_name = None
- for item in definition:
- if type(item) is dict and 'enumtype' in item:
- type_name = item['enumtype']
- continue
- constants.append({'name': item[0], 'value': item[1]})
- if not type_name:
- raise ParseException("'enumtype' was not defined for %s" % definition)
- return Enum(name, Field('value', self._types_by_name[type_name]), constants, definition, self.plugin_name)
-
- def _parse_union(self, name, definition):
- self.logger.debug("Parsing union %s: %s", name, definition)
- crc, fields = self._parse_fields(definition)
- return Union(name, crc, fields, definition, self.plugin_name)
-
- def _parse_type(self, name, definition):
- self.logger.debug("Parsing type %s: %s", name, definition)
- crc, fields = self._parse_fields(definition)
- return Class(name, crc, fields, definition, self.plugin_name)
-
- def _parse_services(self):
- self._dumps_by_details = {}
- self._requests_by_reply = {}
- for name, service in self._services.iteritems():
- if _is_stream(service):
- self._dumps_by_details[service['reply']] = name
- else:
- self._requests_by_reply[service['reply']] = name
-
- def _parse_messages(self):
- # Preserve ordering from JSON file to make debugging easier.
- self._messages_by_name = OrderedDict()
- for msg in self._messages:
- try:
- name = msg[0]
- definition = msg[1:]
- self._messages_by_name[name] = self._parse_message(name, definition)
- except ParseException as e:
- self.logger.warning("Failed to parse message %s: %s. Skipping message.", name, e)
-
- def _parse_message(self, name, definition):
- self.logger.debug("Parsing message %s: %s", name, definition)
- crc, fields = self._parse_fields(definition)
- if name in self._services:
- service = self._services[name]
- reply = service['reply']
- if _is_stream(service):
- return Dump(name, reply, crc, filter(_is_request_field, fields), definition)
- if reply:
- return Request(name, reply, crc, filter(_is_request_field, fields), definition)
- else:
- return Event(name, crc, filter(_is_request_field, fields), definition)
- elif name in self._requests_by_reply:
- return Reply(name, self._requests_by_reply[name], crc, filter(_is_reply_field, fields), definition)
- elif name in self._dumps_by_details:
- return Details(name, self._dumps_by_details[name], crc, filter(_is_reply_field, fields), definition)
- else:
- # TODO: some messages like combined_counters are not visible in the services.
- # Throw exception instead (requires fixing vppagigen).
- return Event(name, crc, filter(_is_request_field, fields), definition)
-
- def _parse_fields(self, definition):
- crc = None
- fields = []
- for item in definition:
- if type(item) == dict and 'crc' in item:
- crc = item['crc']
- else:
- fields.append(self._parse_field(item, fields))
- if not crc:
- raise ParseException("CRC was not defined for %s" % definition)
- return crc, fields
-
- def _parse_field(self, field, fields):
- type_name = _extract_type_name(field[0])
-
- if type_name in self._types_by_name:
- if len(field) > 2:
- # Array field
- array_len_field = None
- if len(field) == 4:
- for f in fields:
- if f.name == field[3]:
- array_len_field = f
- if not array_len_field:
- raise ParseException("Could not find field %s declared as length of array %s",
- field[3], field[1])
- return Field(field[1], self._types_by_name[type_name + _ARRAY_SUFFIX], field[2], array_len_field)
- else:
- return Field(field[1], self._types_by_name[type_name])
- else:
- raise ParseException("Unknown field type %s" % field)
-
- def _validate_messages(self):
- """
- In case if message A is known to be reply for message B, and message B was not correctly parsed,
- remove message A from the set of all messages.
- """
- to_be_removed = []
- messages = self._messages_by_name
- for name, msg in messages.iteritems():
- if (is_request(msg) and msg.reply not in messages) \
- or (is_reply(msg) and msg.request not in messages) \
- or (is_dump(msg) and msg.details not in messages) \
- or (is_details(msg) and msg.dump not in messages):
- to_be_removed.append(name)
-
- for name in to_be_removed:
- del messages[name]
-
- self.messages = self._messages_by_name.values()
-
-
-_ARRAY_SUFFIX = '[]'
-
-
-def _underscore_to_camelcase_upper(name):
- return name.title().replace("_", "")
-
-
-def _underscore_to_camelcase_lower(name):
- name = name.title().replace("_", "")
- return name[0].lower() + name[1:]
-
-
-def _message_to_javadoc(message_definition):
- """ Converts JSON message definition to javadoc """
- formatted_message = pprint.pformat(message_definition, indent=4, width=120, depth=None)
- return " * " + formatted_message.replace("\n", "\n * ")
-
-
-def _is_stream(service):
- """
- Checks if service represents stream, e.g.:
- "ip_address_dump": {
- "reply": "ip_address_details",
- "stream": true
- }
- :param service: JSON definition of service
- :return: value assigned to "stream" or None
- """
- return "stream" in service
-
-
-def _extract_type_name(name):
- if name.startswith(_VPP_TYPE_PREFIX) and name.endswith(_VPP_TYPE_SUFFIX):
- return name[len(_VPP_TYPE_PREFIX): - len(_VPP_TYPE_SUFFIX)]
- return name
-
-_VPP_TYPE_PREFIX = "vl_api_"
-
-_VPP_TYPE_SUFFIX = "_t"
-
-
-def _is_request_field(field):
- # Skip fields that are hidden to the jvpp user (handled by JNI layer)
- return field.name not in {'_vl_msg_id', 'client_index', 'context'}
-
-
-def _is_reply_field(field):
- # Skip fields that are hidden to the jvpp user:
- # _vl_msg_id is handled at JNI layer,
- # Unlike in the request case, context is visible to allow matching replies with requests at Java layer.
- return field.name not in {'_vl_msg_id'}
diff --git a/extras/japi/java/jvpp/gen/jvppgen/notification_gen.py b/extras/japi/java/jvpp/gen/jvppgen/notification_gen.py
deleted file mode 100644
index fa86fe4bbf2..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/notification_gen.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_model import is_control_ping, is_control_ping_reply, is_dump, is_request
-
-
-def generate_notifications(work_dir, model, logger):
- """ Generates notification registry interface and implementation """
- logger.debug("Generating Notification interfaces and implementation for %s" % model.json_api_files)
- messages = filter(_notification_filter, model.messages)
- _generate_global_event_callback(work_dir, model, messages)
- _generate_event_registry(work_dir, model, messages)
- _generate_event_registry_impl(work_dir, model, messages)
- _generate_event_registry_provider(work_dir, model)
-
-
-def _notification_filter(msg):
- # Generate callbacks for all messages except for dumps and requests (handled by vpp, not client).
- # Also skip control ping managed by jvpp registry.
- return (not is_control_ping(msg)) and \
- (not is_control_ping_reply(msg)) and \
- (not is_dump(msg)) and \
- (not is_request(msg))
-
-
-def _generate_event_registry(work_dir, model, messages):
- plugin_name = model.plugin_java_name
- plugin_package = model.plugin_package
-
- register_callback_methods = []
- for msg in messages:
- name = _callback_name(msg)
- fqn_name = _fqn_callback_name(plugin_package, name)
- # TODO create NotificationListenerRegistration and return that instead of AutoCloseable to better indicate
- # that the registration should be closed
- register_callback_methods.append(" java.lang.AutoCloseable register%s(%s callback);" % (name, fqn_name))
-
- with open("%s/%sEventRegistry.java" % (work_dir, plugin_name), "w") as f:
- f.write(_EVENT_REGISTRY_TEMPLATE.substitute(
- plugin_package=plugin_package,
- plugin_name=plugin_name,
- json_filename=model.json_api_files,
- register_callback_methods="\n".join(register_callback_methods)
- ))
-
-_EVENT_REGISTRY_TEMPLATE = Template("""
-package $plugin_package.notification;
-
-/**
- * <p>Registry for notification callbacks defined in ${plugin_name}.
- * <br>It was generated by notification_gen.py based on $json_filename.
- */
-public interface ${plugin_name}EventRegistry extends io.fd.vpp.jvpp.notification.EventRegistry {
-
-$register_callback_methods
-
- @Override
- void close();
-}
-""")
-
-
-def _generate_event_registry_impl(work_dir, model, messages):
- plugin_name = model.plugin_java_name
- plugin_package = model.plugin_package
-
- register_callback_methods = []
- handler_methods = []
- for msg in messages:
- notification = msg.java_name_upper
- callback = "%sCallback" % notification
- register_callback_methods.append(_REGISTER_CALLBACK_IMPL_TEMPLATE.substitute(
- plugin_package=plugin_package,
- notification=notification,
- callback=callback
- ))
- handler_methods.append(_HANDLER_IMPL_TEMPLATE.substitute(
- plugin_package=plugin_package,
- notification=notification,
- callback=callback
- ))
-
- with open("%s/%sEventRegistryImpl.java" % (work_dir, plugin_name), "w") as f:
- f.write(_EVENT_REGISTRY_IMPL_TEMPLATE.substitute(
- plugin_package=plugin_package,
- plugin_name=plugin_name,
- json_filename=model.json_api_files,
- register_callback_methods="".join(register_callback_methods),
- handler_methods="".join(handler_methods)
- ))
-
-_REGISTER_CALLBACK_IMPL_TEMPLATE = Template("""
- public java.lang.AutoCloseable register$callback(final $plugin_package.callback.$callback callback){
- if(null != registeredCallbacks.putIfAbsent($plugin_package.dto.$notification.class, callback)){
- throw new IllegalArgumentException("Callback for " + $plugin_package.dto.$notification.class +
- "notification already registered");
- }
- return () -> registeredCallbacks.remove($plugin_package.dto.$notification.class);
- }
-""")
-
-_HANDLER_IMPL_TEMPLATE = Template("""
- @Override
- public void on$notification(
- final $plugin_package.dto.$notification notification) {
- if (LOG.isLoggable(java.util.logging.Level.FINE)) {
- LOG.fine(java.lang.String.format("Received $notification event message: %s", notification));
- }
- final io.fd.vpp.jvpp.callback.JVppCallback jVppCallback = registeredCallbacks.get($plugin_package.dto.$notification.class);
- if (null != jVppCallback) {
- (($plugin_package.callback.$callback) registeredCallbacks
- .get($plugin_package.dto.$notification.class))
- .on$notification(notification);
- }
- }
-""")
-
-_EVENT_REGISTRY_IMPL_TEMPLATE = Template("""
-package $plugin_package.notification;
-
-/**
- * <p>Notification registry delegating notification processing to registered callbacks.
- * <br>It was generated by notification_gen.py based on $json_filename.
- */
-public final class ${plugin_name}EventRegistryImpl implements ${plugin_name}EventRegistry, Global${plugin_name}EventCallback {
-
- // TODO add a special NotificationCallback interface and only allow those to be registered
- private final java.util.concurrent.ConcurrentMap<Class<?>, io.fd.vpp.jvpp.callback.JVppCallback> registeredCallbacks =
- new java.util.concurrent.ConcurrentHashMap<>();
- private static java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(${plugin_name}EventRegistryImpl.class.getName());
-
- $register_callback_methods
- $handler_methods
-
- @Override
- public void close() {
- registeredCallbacks.clear();
- }
-
- @Override
- public void onError(io.fd.vpp.jvpp.VppCallbackException ex) {
- java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(${plugin_name}EventRegistryImpl.class.getName());
- LOG.log(java.util.logging.Level.WARNING, java.lang.String.format("Received onError exception: call=%s, context=%d, retval=%d%n", ex.getMethodName(),
- ex.getCtxId(), ex.getErrorCode()), ex);
- }
-}
-""")
-
-
-def _generate_global_event_callback(work_dir, model, messages):
- plugin_name = model.plugin_java_name
- plugin_package = model.plugin_package
-
- callbacks = ""
- callback_list = []
- for msg in messages:
- fqn_name = _fqn_callback_name(plugin_package, _callback_name(msg))
- callback_list.append(fqn_name)
-
- if callback_list:
- callbacks = " extends %s" % ", ".join(callback_list)
-
- with open("%s/Global%sEventCallback.java" % (work_dir, plugin_name), "w") as f:
- f.write(_GLOBAL_EVENT_CALLBACK_TEMPLATE.substitute(
- plugin_package=plugin_package,
- plugin_name=plugin_name,
- json_filename=model.json_api_files,
- callbacks=callbacks
- ))
-
-_GLOBAL_EVENT_CALLBACK_TEMPLATE = Template("""
-package $plugin_package.notification;
-
-/**
- * <p>Aggregated callback interface for notifications only.
- * <br>It was generated by notification_gen.py based on $json_filename.
- */
-public interface Global${plugin_name}EventCallback$callbacks {
-
-}
-""")
-
-
-def _generate_event_registry_provider(work_dir, model):
- plugin_name = model.plugin_java_name
- with open("%s/%sEventRegistryProvider.java" % (work_dir, plugin_name), "w") as f:
- f.write(_EVENT_REGISTRY_PROVIDER_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- plugin_name=plugin_name,
- json_filename=model.json_api_files
- ))
-
-_EVENT_REGISTRY_PROVIDER_TEMPLATE = Template("""
-package $plugin_package.notification;
-
- /**
- * Provides ${plugin_name}EventRegistry.
- * <br>The file was generated by notification_gen.py based on $json_filename.
- */
-public interface ${plugin_name}EventRegistryProvider extends io.fd.vpp.jvpp.notification.EventRegistryProvider {
-
- @Override
- public ${plugin_name}EventRegistry getEventRegistry();
-}
-""")
-
-
-def _callback_name(msg):
- return "%sCallback" % msg.java_name_upper
-
-
-def _fqn_callback_name(plugin_package, callback_name):
- return "%s.callback.%s" % (plugin_package, callback_name)
diff --git a/extras/japi/java/jvpp/gen/jvppgen/types_gen.py b/extras/japi/java/jvpp/gen/jvppgen/types_gen.py
deleted file mode 100755
index 3767b530347..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/types_gen.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2016,2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from string import Template
-
-from jvpp_common_gen import generate_hash_code, generate_equals, generate_to_string, generate_fields
-from jvpp_model import Class
-
-
-def generate_types(work_dir, model, logger):
- logger.debug("Generating custom types for %s " % model.json_api_files)
-
- for t in model.types:
- if not isinstance(t, Class):
- continue
- logger.debug("Generating DTO for type %s", t)
- type_class_name = t.java_name
- fields = t.fields
- type_class = _TYPE_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- c_type_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- java_type_name=type_class_name,
- fields=generate_fields(fields),
- hash_code=generate_hash_code(fields),
- equals=generate_equals(type_class_name, fields),
- to_string=generate_to_string(type_class_name, fields)
- )
- with open("%s/%s.java" % (work_dir, type_class_name), "w") as f:
- f.write(type_class)
-
-_TYPE_TEMPLATE = Template("""
-package $plugin_package.types;
-
-/**
- * <p>This class represents $c_type_name type definition.
- * <br>It was generated by jvpp_types_gen.py based on $json_filename:
- * <pre>
-$json_definition
- * </pre>
- */
-public final class $java_type_name {
-$fields
-$hash_code
-$equals
-$to_string
-}
-""")
diff --git a/extras/japi/java/jvpp/gen/jvppgen/unions_gen.py b/extras/japi/java/jvpp/gen/jvppgen/unions_gen.py
deleted file mode 100755
index f67704f2426..00000000000
--- a/extras/japi/java/jvpp/gen/jvppgen/unions_gen.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python2
-#
-# Copyright (c) 2018 Cisco and/or its affiliates.
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from string import Template
-
-from jvpp_common_gen import generate_hash_code, generate_equals, generate_to_string, generate_fields
-from jvpp_model import Union
-
-
-def generate_unions(work_dir, model, logger):
- logger.debug("Generating unions for %s " % model.json_api_files)
-
- for t in model.types:
- if not isinstance(t, Union):
- continue
- logger.debug("Generating DTO for union %s", t)
- java_union_name = t.java_name
- fields = t.fields
- type_class = _UNION_TEMPLATE.substitute(
- plugin_package=model.plugin_package,
- c_type_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- java_union_name=java_union_name,
- fields=generate_fields(fields, access_modifier="private"),
- constructors=_generate_constructors(java_union_name, fields),
- getters=_generate_getters(fields),
- hash_code=generate_hash_code(fields),
- equals=generate_equals(java_union_name, fields),
- to_string=generate_to_string(java_union_name, fields)
- )
- with open("%s/%s.java" % (work_dir, java_union_name), "w") as f:
- f.write(type_class)
-
-_UNION_TEMPLATE = Template("""
-package ${plugin_package}.types;
-
-/**
- * <p>This class represents ${c_type_name} union definition.
- * <br>It was generated by unions_gen.py based on ${json_filename}:
- * <pre>
-${json_definition}
- * </pre>
- */
-public class ${java_union_name} {
- private final int _activeMember;
-${fields}
- private ${java_union_name}() {
- // Constructor for JNI usage. All members can be read.
- _activeMember = -1;
- }
-${constructors}
-${getters}
-${hash_code}
-${equals}
-${to_string}
-}
-""")
-
-
-def _generate_constructors(union_name, fields):
- return "".join(
- _CONSTRUCTOR_TEMPLATE
- .substitute(union_name=union_name,
- field_type=f.type.java_name_fqn,
- field_name=f.java_name,
- field_index=i) for i, f in enumerate(fields))
-
-_CONSTRUCTOR_TEMPLATE = Template("""
- public ${union_name}(${field_type} ${field_name}) {
- this.${field_name} = java.util.Objects.requireNonNull(${field_name}, "${field_name} should not be null");
- _activeMember = $field_index;
- }""")
-
-
-def _generate_getters(fields):
- return "".join(_GETTER_TEMPLATE.substitute(
- type=f.type.java_name_fqn,
- getter_name=f.java_name_upper,
- field_name=f.java_name
- ) for f in fields)
-
-_GETTER_TEMPLATE = Template("""
- public ${type} get${getter_name}() {
- return ${field_name};
- }""")