<commit_before>#  ----------------------------------------------------------------
# Copyright 2016 Cisco Systems
#
# 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.
# ------------------------------------------------------------------

"""
source_printer.py

 prints Go class constructor

"""
from functools import reduce

from ydkgen.api_model import Bits, Class, DataType, Enum
from ydkgen.builder import TypesExtractor
from pyang.types import Decimal64TypeSpec, PathTypeSpec, UnionTypeSpec
from ydkgen.printer.meta_data_util import get_class_docstring, get_meta_info_data, format_range_string
from .function_printer import FunctionPrinter

class ClassConstructorPrinter(FunctionPrinter):
    def __init__(self, ctx, clazz, leafs, identity_subclasses):
        super(ClassConstructorPrinter, self).__init__(ctx, clazz, leafs)
        self.identity_subclasses = identity_subclasses

    def print_function_header(self):
        self._print_docstring()
        self.ctx.writeln('type %s struct {' % self.clazz.qualified_go_name())
        self.ctx.lvl_inc()

    def print_function_body(self):
        self.ctx.writeln('EntityData types.CommonEntityData')
        self.ctx.writeln('YFilter yfilter.YFilter')
        if self.clazz.stmt.search_one('presence') is not None:
            self.ctx.writeln('YPresence bool')
        self._print_inits()

    def _print_docstring(self):
        self.ctx.writeln('// %s' % self.clazz.qualified_go_name())
        lines = []
        # class comment

        if self.clazz.comment is not None:
            lines.extend(self.clazz.comment.split('\n'))

        # presence statement
        if self.clazz.stmt.search_one('presence') is not None:
            lines.append('This type is a presence type.')

        for l in lines:
            self.ctx.writeln('// %s' % l)

    def _print_inits(self):
        self._print_leaf_inits()
        self._print_children_inits()

    def _print_leaf_inits(self):
        index = 0
        while index < len(self.leafs):
            self.ctx.bline()
            prop = self.leafs[index]
            index += 1

            leaf_name = prop.go_name()
            type_name = get_type_name(prop.property_type)

            if prop.is_many:
                declaration_stmt = '%s []interface{}' % leaf_name
            else:
                declaration_stmt = '%s interface{}' % leaf_name

            comments = self._get_attribute_comment(prop, type_name)
            self.ctx.writelns(comments)
            self.ctx.bline()
            self.ctx.writeln(declaration_stmt)

    def _print_children_inits(self):
        for prop in self.clazz.properties():
            if not prop.is_many:
                self._print_child_inits_unique(prop)
            elif prop.stmt.keyword != 'anyxml':
                self._print_child_inits_many(prop)

    def _print_child_inits_unique(self, prop):
        if (isinstance(prop.property_type, Class)
            and not prop.property_type.is_identity()):
            self.ctx.bline()

            comments = []
            self._add_comment_on_prop(prop, comments)
            self.ctx.writelns(self._get_formatted_comment(comments))
            self.ctx.bline()

            self.ctx.writeln('%s %s' % (
                prop.property_type.go_name(), prop.property_type.qualified_go_name()))

    def _print_child_inits_many(self, prop):
        if (prop.is_many and isinstance(prop.property_type, Class)
            and not prop.property_type.is_identity()):
            self.ctx.bline()

            comments = self._get_attribute_comment(prop)
            self.ctx.writelns(comments)
            self.ctx.bline()

            self.ctx.writeln('%s []*%s' % (
                prop.property_type.go_name(), prop.property_type.qualified_go_name()))

    def _get_formatted_comment(self, comments):
        comments = ' '.join(comments)
        comments = comments.split(' ')
        line = ''
        result = []
        for word in comments:
            _line = '%s %s' % (line, word)
            if line == '':
                line = word
            elif len(_line) > 75:
                result.append('// %s' % line)
                line = word
            else:
                line = _line
        if line != '':
            result.append('// %s' % line)
        return result

    def _get_attribute_comment(self, prop, type_name=None):
        properties_description = []
        meta_info_data = self._get_meta_info_data(prop)
        self._add_comment_on_key(prop, properties_description)
        self._add_comment_on_prop(prop, properties_description)
        self._add_comment_on_presence(prop, properties_description)
        # self._add_comment_on_expected_type(prop, properties_description, type_name, meta_info_data)

        # More Comments
        properties_description.append('The type is')
        properties_description.extend(self._get_type_doc(meta_info_data, 1))
        formatted_comment = self._get_formatted_comment(properties_description)
        return formatted_comment

    def _get_meta_info_data(self, prop):
        property_type = prop.property_type
        type_stmt = prop.stmt.search_one('type')

        id_subclasses = None
        if (hasattr(property_type, 'is_identity') and property_type.is_identity()):
            id_subclasses = self.identity_subclasses

        meta_info_data = get_meta_info_data(
            prop, property_type, type_stmt, 'go', False, identity_subclasses=id_subclasses)

        if type(prop.property_type) in (Class, Enum, Bits):
            meta_info_data.clazz_name = "'%s'" % property_type.qualified_go_name()

        if isinstance(prop.property_type, Class):
            if id_subclasses is None:
                meta_info_data.doc_link = prop.qualified_go_name()
            else:<commit_msg>Added capability to generate meta-data in Python bundles<commit_after>#  ----------------------------------------------------------------
# Copyright 2016 Cisco Systems
#
# 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.
# ------------------------------------------------------------------

"""
source_printer.py

 prints Go class constructor

"""
from functools import reduce

from ydkgen.api_model import Bits, Class, DataType, Enum
from ydkgen.builder import TypesExtractor
from pyang.types import Decimal64TypeSpec, PathTypeSpec, UnionTypeSpec
from ydkgen.printer.meta_data_util import get_class_docstring, get_meta_info_data, format_range_string
from .function_printer import FunctionPrinter

class ClassConstructorPrinter(FunctionPrinter):
    def __init__(self, ctx, clazz, leafs, identity_subclasses):
        super(ClassConstructorPrinter, self).__init__(ctx, clazz, leafs)
        self.identity_subclasses = identity_subclasses

    def print_function_header(self):
        self._print_docstring()
        self.ctx.writeln('type %s struct {' % self.clazz.qualified_go_name())
        self.ctx.lvl_inc()

    def print_function_body(self):
        self.ctx.writeln('EntityData types.CommonEntityData')
        self.ctx.writeln('YFilter yfilter.YFilter')
        if self.clazz.stmt.search_one('presence') is not None:
            self.ctx.writeln('YPresence bool')
        self._print_inits()

    def _print_docstring(self):
        self.ctx.writeln('// %s' % self.clazz.qualified_go_name())
        lines = []
        # class comment

        if self.clazz.comment is not None:
            lines.extend(self.clazz.comment.split('\n'))

        # presence statement
        if self.clazz.stmt.search_one('presence') is not None:
            lines.append('This type is a presence type.')

        for l in lines:
            self.ctx.writeln('// %s' % l)

    def _print_inits(self):
        self._print_leaf_inits()
        self._print_children_inits()

    def _print_leaf_inits(self):
        index = 0
        while index < len(self.leafs):
            self.ctx.bline()
            prop = self.leafs[index]
            index += 1

            leaf_name = prop.go_name()
            type_name = get_type_name(prop.property_type)

            if prop.is_many:
                declaration_stmt = '%s []interface{}' % leaf_name
            else:
                declaration_stmt = '%s interface{}' % leaf_name

            comments = self._get_attribute_comment(prop, type_name)
            self.ctx.writelns(comments)
            self.ctx.bline()
            self.ctx.writeln(declaration_stmt)

    def _print_children_inits(self):
        for prop in self.clazz.properties():
            if not prop.is_many:
                self._print_child_inits_unique(prop)
            elif prop.stmt.keyword != 'anyxml':
                self._print_child_inits_many(prop)

    def _print_child_inits_unique(self, prop):
        if (isinstance(prop.property_type, Class)
            and not prop.property_type.is_identity()):
            self.ctx.bline()

            comments = []
            self._add_comment_on_prop(prop, comments)
            self.ctx.writelns(self._get_formatted_comment(comments))
            self.ctx.bline()

            self.ctx.writeln('%s %s' % (
                prop.property_type.go_name(), prop.property_type.qualified_go_name()))

    def _print_child_inits_many(self, prop):
        if (prop.is_many and isinstance(prop.property_type, Class)
            and not prop.property_type.is_identity()):
            self.ctx.bline()

            comments = self._get_attribute_comment(prop)
            self.ctx.writelns(comments)
            self.ctx.bline()

            self.ctx.writeln('%s []*%s' % (
                prop.property_type.go_name(), prop.property_type.qualified_go_name()))

    def _get_formatted_comment(self, comments):
        comments = ' '.join(comments)
        comments = comments.split(' ')
        line = ''
        result = []
        for word in comments:
            _line = '%s %s' % (line, word)
            if line == '':
                line = word
            elif len(_line) > 75:
                result.append('// %s' % line)
                line = word
            else:
                line = _line
        if line != '':
            result.append('// %s' % line)
        return result

    def _get_attribute_comment(self, prop, type_name=None):
        properties_description = []
        meta_info_data = self._get_meta_info_data(prop)
        self._add_comment_on_key(prop, properties_description)
        self._add_comment_on_prop(prop, properties_description)
        self._add_comment_on_presence(prop, properties_description)
        # self._add_comment_on_expected_type(prop, properties_description, type_name, meta_info_data)

        # More Comments
        properties_description.append('The type is')
        properties_description.extend(self._get_type_doc(meta_info_data, 1))
        formatted_comment = self._get_formatted_comment(properties_description)
        return formatted_comment

    def _get_meta_info_data(self, prop):
        property_type = prop.property_type
        type_stmt = prop.stmt.search_one('type')

        id_subclasses = None
        if (hasattr(property_type, 'is_identity') and property_type.is_identity()):
            id_subclasses = self.identity_subclasses

        meta_info_data = get_meta_info_data(
            prop, property_type, type_stmt, 'go', identity_subclasses=id_subclasses)

        if type(prop.property_type) in (Class, Enum, Bits):
            meta_info_data.clazz_name = "'%s'" % property_type.qualified_go_name()

        if isinstance(prop.property_type, Class):
            if id_subclasses is None:
                meta_info_data.doc_link = prop.qualified_go_name()
            else:
{'fraction_non_alphanumeric': 0.11488955982838074, 'fraction_numerical': 0.002383600826314953, 'mean_word_length': 2.358324439701174, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6194098', 'n_tokens_mistral': 3669, 'n_tokens_neox': 3559, 'n_words': 785}