Пример #1
0
        MOBILE = 0;
        HOME = 1;
        WORK = 2;
      }

      message PhoneNumber {
        required string number = 1;
        optional PhoneType type = 2 [default = HOME];
      }

      repeated PhoneNumber phone = 4;
      extensions 500 to 990;
}

message AddressBook {
  repeated Person person = 1;

  // Possible extension numbers.
  extensions 500 to max;
}"""

test4 = '''policy foo <exists foo: foo.x=foo.y>'''
parser = plyproto.ProtobufAnalyzer()

tests = globals()

for t in tests:
    if t.startswith('test'):
        print 'parsin %s' % t
        parser.parse_string(globals()[t])
Пример #2
0
    def generate(args):

        # Setting defaults
        if not hasattr(args, 'attic'):
            args.attic = None
        if not hasattr(args, 'write_to_file'):
            args.write_to_file = None
        if not hasattr(args, 'dest_file'):
            args.dest_file = None
        if not hasattr(args, 'dest_extension'):
            args.dest_extension = None
        if not hasattr(args, 'output'):
            args.output = None
        if not hasattr(args, 'quiet'):
            args.quiet = True

        # Validating
        if args.write_to_file == 'single' and args.dest_file is None:
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'single' but no dest_file is provided"
            )
        if args.write_to_file == 'model' and args.dest_extension is None:
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'model' but no dest_extension is provided"
            )

        if args.output is not None and not os.path.isabs(args.output):
            raise Exception(
                "[XosGenX] The output dir must be an absolute path!")
        if args.output is not None and not os.path.isdir(args.output):
            raise Exception("[XosGenX] The output dir must be a directory!")

        if hasattr(args, 'files'):
            inputs = XOSGenerator._read_input_from_files(args.files)
        elif hasattr(args, 'inputs'):
            inputs = args.inputs
        else:
            raise Exception("[XosGenX] No inputs provided!")

        template_path = XOSGenerator._get_template(args.target)
        [template_folder, template_name] = os.path.split(template_path)
        os_template_loader = jinja2.FileSystemLoader(
            searchpath=[template_folder])
        os_template_env = jinja2.Environment(loader=os_template_loader)
        os_template_env = XOSGenerator._load_jinja2_extensions(
            os_template_env, args.attic)
        template = os_template_env.get_template(template_name)
        context = XOSGenerator._add_context(args)

        parser = plyxproto.ProtobufAnalyzer()
        ast = parser.parse_string(inputs, debug=0)
        v = XOSGenerator._attach_parser(ast, args)

        if args.output is not None and args.write_to_file == "model":
            rendered = {}
            for i, model in enumerate(v.models):
                models = {}
                models[model] = v.models[model]
                messages = [
                    XOSGenerator._find_message_by_model_name(
                        v.messages, model)
                ]

                rendered[model] = template.render({
                    "proto": {
                        'message_table': models,
                        'messages': messages,
                        'policies': v.policies,
                        'message_names': [m['name'] for m in messages]
                    },
                    "context": context,
                    "options": v.options
                })
            XOSGenerator._write_file_per_model(rendered, args.output,
                                               args.dest_extension, args.quiet)
        else:
            rendered = template.render({
                "proto": {
                    'message_table': v.models,
                    'messages': v.messages,
                    'policies': v.policies,
                    'message_names': [m['name'] for m in v.messages]
                },
                "context": context,
                "options": v.options
            })
            if args.output is not None and args.write_to_file == "target":
                XOSGenerator._write_split_target(rendered, args.output,
                                                 args.quiet)
            elif args.output is not None and args.write_to_file == "single":
                XOSGenerator._write_single_file(rendered, args.output,
                                                args.dest_file, args.quiet)

        return rendered
Пример #3
0
    def process(args, operator=None):
        # Setting defaults
        if not hasattr(args, "attic"):
            args.attic = None
        if not hasattr(args, "write_to_file"):
            args.write_to_file = None
        if not hasattr(args, "dest_file"):
            args.dest_file = None
        if not hasattr(args, "dest_extension"):
            args.dest_extension = None
        if not hasattr(args, "output"):
            args.output = None
        if not hasattr(args, "quiet"):
            args.quiet = True

        # Validating
        if args.write_to_file == "single" and args.dest_file is None:
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'single' but no dest_file is provided"
            )
        if args.write_to_file == "model" and (args.dest_extension is None):
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'model' but no dest_extension is provided"
            )

        if args.output is not None and not os.path.isabs(args.output):
            raise Exception(
                "[XosGenX] The output dir must be an absolute path!")
        if args.output is not None and not os.path.isdir(args.output):
            raise Exception("[XosGenX] The output dir must be a directory!")

        if hasattr(args, "files"):
            inputs = XOSProcessor._read_input_from_files(args.files)
        elif hasattr(args, "inputs"):
            inputs = args.inputs
        else:
            raise Exception("[XosGenX] No inputs provided!")

        if not operator:
            operator = args.target
            template_path = XOSProcessor._get_template(operator)
        else:
            template_path = operator

        [template_folder, template_name] = os.path.split(template_path)
        os_template_loader = jinja2.FileSystemLoader(
            searchpath=[template_folder])
        os_template_env = jinja2.Environment(loader=os_template_loader)
        os_template_env = XOSProcessor._load_jinja2_extensions(
            os_template_env, args.attic)
        template = os_template_env.get_template(template_name)
        context = XOSProcessor._add_context(args)

        parser = plyxproto.ProtobufAnalyzer()
        try:
            ast = parser.parse_string(inputs, debug=0)
        except plyxproto.ParsingError as e:
            line, start, end = e.error_range

            ptr = XOSProcessor._find_last_nonempty_line(inputs, start)

            if start == 0:
                beginning = ""
            else:
                beginning = inputs[ptr:start - 1]

            line_end_char = inputs[start + end:].find("\n")
            line_end = inputs[line_end_char]

            if e.message:
                error = e.message
            else:
                error = "xproto parsing error"

            print(error + "\n" + Fore.YELLOW + "Line %d:" % line + Fore.WHITE)
            print(beginning + Fore.YELLOW + inputs[start - 1:start + end] +
                  Fore.WHITE + line_end)
            exit(1)

        v = XOSProcessor._attach_parser(ast, args)

        if args.include_models or args.include_apps:
            for message in v.messages:
                message["is_included"] = False
                if message["name"] in args.include_models:
                    message["is_included"] = True
                else:
                    app_label = message.get("options",
                                            {}).get("app_label").strip('"')
                    if app_label in args.include_apps:
                        message["is_included"] = True
        else:
            for message in v.messages:
                message["is_included"] = True

        if args.output is not None and args.write_to_file == "model":
            rendered = {}
            for i, model in enumerate(v.models):
                models = {}
                models[model] = v.models[model]
                messages = [
                    XOSProcessor._find_message_by_model_name(
                        v.messages, model)
                ]

                rendered[model] = template.render({
                    "proto": {
                        "message_table": models,
                        "messages": messages,
                        "policies": v.policies,
                        "message_names": [m["name"] for m in v.messages],
                    },
                    "context": context,
                    "options": v.options,
                })
            if str(v.options.get("legacy",
                                 "false")).strip('"').lower() == "true":
                suffix = "_decl." + args.dest_extension
            else:
                suffix = "." + args.dest_extension
            XOSProcessor._write_file_per_model(rendered, args.output, suffix,
                                               args.quiet)
        else:
            rendered = template.render({
                "proto": {
                    "message_table": v.models,
                    "messages": v.messages,
                    "policies": v.policies,
                    "message_names": [m["name"] for m in v.messages],
                },
                "context": context,
                "options": v.options,
            })
            if args.output is not None and args.write_to_file == "target":
                XOSProcessor._write_split_target(rendered, args.output,
                                                 args.quiet)
            elif args.output is not None and args.write_to_file == "single":
                XOSProcessor._write_single_file(rendered, args.output,
                                                args.dest_file, args.quiet)

        return rendered
Пример #4
0
    def process(args, operator=None):
        # Setting defaults
        if not hasattr(args, 'attic'):
            args.attic = None
        if not hasattr(args, 'write_to_file'):
            args.write_to_file = None
        if not hasattr(args, 'dest_file'):
            args.dest_file = None
        if not hasattr(args, 'dest_extension'):
            args.dest_extension = None
        if not hasattr(args, 'output'):
            args.output = None
        if not hasattr(args, 'quiet'):
            args.quiet = True

        # Validating
        if args.write_to_file == 'single' and args.dest_file is None:
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'single' but no dest_file is provided"
            )
        if args.write_to_file == 'model' and (args.dest_extension is None):
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'model' but no dest_extension is provided"
            )

        if args.output is not None and not os.path.isabs(args.output):
            raise Exception(
                "[XosGenX] The output dir must be an absolute path!")
        if args.output is not None and not os.path.isdir(args.output):
            raise Exception("[XosGenX] The output dir must be a directory!")

        if hasattr(args, 'files'):
            inputs = XOSProcessor._read_input_from_files(args.files)
        elif hasattr(args, 'inputs'):
            inputs = args.inputs
        else:
            raise Exception("[XosGenX] No inputs provided!")

        if not operator:
            operator = args.target
            template_path = XOSProcessor._get_template(operator)
        else:
            template_path = operator

        [template_folder, template_name] = os.path.split(template_path)
        os_template_loader = jinja2.FileSystemLoader(
            searchpath=[template_folder])
        os_template_env = jinja2.Environment(loader=os_template_loader)
        os_template_env = XOSProcessor._load_jinja2_extensions(
            os_template_env, args.attic)
        template = os_template_env.get_template(template_name)
        context = XOSProcessor._add_context(args)

        parser = plyxproto.ProtobufAnalyzer()
        try:
            ast = parser.parse_string(inputs, debug=0)
        except plyxproto.ParsingError, e:
            line, start, end = e.error_range

            ptr = XOSProcessor._find_last_nonempty_line(inputs, start)

            if start == 0:
                beginning = ''
            else:
                beginning = inputs[ptr:start - 1]

            line_end_char = inputs[start + end:].find('\n')
            line_end = inputs[line_end_char]

            if e.message:
                error = e.message
            else:
                error = "xproto parsing error"

            print error + "\n" + Fore.YELLOW + "Line %d:" % line + Fore.WHITE
            print beginning + Fore.YELLOW + inputs[start - 1:start +
                                                   end] + Fore.WHITE + line_end
            exit(1)
Пример #5
0
    def process(args, operator=None):
        # Setting defaults
        if not hasattr(args, "attic"):
            args.attic = None
        if not hasattr(args, "write_to_file"):
            args.write_to_file = None
        if not hasattr(args, "dest_file"):
            args.dest_file = None
        if not hasattr(args, "dest_extension"):
            args.dest_extension = None
        if not hasattr(args, "output"):
            args.output = None
        if not hasattr(args, "quiet"):
            args.quiet = True

        # Validating
        if args.write_to_file == "single" and args.dest_file is None:
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'single' but no dest_file is provided"
            )
        if args.write_to_file == "model" and (args.dest_extension is None):
            raise Exception(
                "[XosGenX] write_to_file option is specified as 'model' but no dest_extension is provided"
            )

        if args.output is not None and not os.path.isabs(args.output):
            raise Exception(
                "[XosGenX] The output dir (%s) must be an absolute path!" %
                args.output)
        if args.output is not None and not os.path.isdir(args.output):
            raise Exception(
                "[XosGenX] The output dir (%s) must be a directory!" %
                args.output)

        if hasattr(args, "files"):
            (inputs,
             line_map) = XOSProcessor._read_input_from_files(args.files)
        elif hasattr(args, "inputs"):
            inputs = args.inputs
            line_map = []
        else:
            raise Exception("[XosGenX] No inputs provided!")

        context = XOSProcessor._add_context(args)

        parser = plyxproto.ProtobufAnalyzer()
        try:
            ast = parser.parse_string(inputs, debug=0)
        except plyxproto.ParsingError as e:
            if e.message:
                error = e.message
            else:
                error = "xproto parsing error"
            if e.error_range is None:
                # No line number information
                print(error + "\n")
            else:
                line, start, end = e.error_range

                ptr = XOSProcessor._find_last_nonempty_line(inputs, start)

                if start == 0:
                    beginning = ""
                else:
                    beginning = inputs[ptr:start - 1]

                line_end_char = inputs[start + end:].find("\n")
                line_end = inputs[line_end_char]

                print(error + "\n" + Fore.YELLOW + "Line %d:" % line +
                      Fore.WHITE)
                print(beginning + Fore.YELLOW + inputs[start - 1:start + end] +
                      Fore.WHITE + line_end)
            exit(1)

        v = XOSProcessor._attach_parser(ast, args)

        if args.include_models or args.include_apps:
            for message in v.messages:
                message["is_included"] = False
                if message["name"] in args.include_models:
                    message["is_included"] = True
                else:
                    app_label = (message.get("options",
                                             {}).get("app_label").strip('"'))
                    if app_label in args.include_apps:
                        message["is_included"] = True
        else:
            for message in v.messages:
                message["is_included"] = True

        validator = XProtoValidator(v.models, line_map)
        validator.validate()
        if validator.errors:
            if args.strict_validation or (args.verbosity >= 0):
                validator.print_errors()
            fatal_errors = [
                x for x in validator.errors if x["severity"] == "ERROR"
            ]
            if fatal_errors and args.strict_validation:
                sys.exit(-1)

        if args.lint:
            return ""

        if not operator:
            operator = args.target
            template_path = XOSProcessor._get_template(operator)
        else:
            template_path = operator

        [template_folder, template_name] = os.path.split(template_path)
        os_template_loader = jinja2.FileSystemLoader(
            searchpath=[template_folder])
        os_template_env = jinja2.Environment(loader=os_template_loader)
        os_template_env = XOSProcessor._load_jinja2_extensions(
            os_template_env, args.attic)
        template = os_template_env.get_template(template_name)

        if args.output is not None and args.write_to_file == "model":
            # Handle the case where each model is written to a separate python file.
            rendered = {}

            for i, model in enumerate(v.models):
                model_dict = v.models[model]
                messages = [
                    XOSProcessor._find_message_by_model_name(
                        v.messages, model)
                ]

                rendered[model] = template.render({
                    "proto": {
                        "message_table": {
                            model: model_dict
                        },
                        "messages": messages,
                        "policies": v.policies,
                        "message_names": [m["name"] for m in v.messages],
                    },
                    "context": context,
                    "options": v.options,
                })
                if not rendered[model]:
                    print("Not saving model %s as it is empty" % model,
                          file=sys.stderr)
                else:
                    legacy = jinja2_extensions.base.xproto_list_evaluates_true(
                        [
                            model_dict.get("options",
                                           {}).get("custom_python", None),
                            model_dict.get("options", {}).get("legacy", None),
                            v.options.get("custom_python", None),
                            v.options.get("legacy", None)
                        ])

                    if legacy:
                        file_name = "%s/%s_decl.%s" % (
                            args.output, model.lower(), args.dest_extension)
                    else:
                        file_name = "%s/%s.%s" % (args.output, model.lower(),
                                                  args.dest_extension)

                    file = open(file_name, "w")
                    file.write(rendered[model])
                    file.close()
                    if not args.quiet:
                        print("Saved: %s" % file_name, file=sys.stderr)
        else:
            # Handle the case where all models are written to the same python file.

            rendered = template.render({
                "proto": {
                    "message_table": v.models,
                    "messages": v.messages,
                    "policies": v.policies,
                    "message_names": [m["name"] for m in v.messages],
                },
                "context": context,
                "options": v.options,
            })
            if args.output is not None and args.write_to_file == "target":
                XOSProcessor._write_split_target(rendered, args.output,
                                                 args.quiet)
            elif args.output is not None and args.write_to_file == "single":
                XOSProcessor._write_single_file(rendered, args.output,
                                                args.dest_file, args.quiet)

        return rendered