mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-21 19:33:26 +00:00
Make typo verification more robust
This commit is contained in:
@@ -66,6 +66,19 @@ LABEL_REQUIRED = 2
|
||||
LABEL_REPEATED = 3
|
||||
|
||||
|
||||
def _enum_opt_name(opts, ext):
|
||||
"""Return the value *name* of an enum-typed field extension, or None if
|
||||
unset / the 0 sentinel. The proto enum constrains valid values at protoc
|
||||
time, while the codegen keeps using the name string (which matches the
|
||||
coXXX / ConfigOptionDef::GUIType C++ identifier)."""
|
||||
if not opts.HasExtension(ext):
|
||||
return None
|
||||
val = opts.Extensions[ext]
|
||||
if val == 0:
|
||||
return None
|
||||
return ext.enum_type.values_by_number[val].name
|
||||
|
||||
|
||||
def mode_to_cpp(mode_val):
|
||||
"""Convert mode enum value to C++ constant."""
|
||||
return {
|
||||
@@ -203,7 +216,7 @@ class FieldInfo:
|
||||
self.full_width = opts.Extensions[meta_pb2.full_width]
|
||||
self.height = opts.Extensions[meta_pb2.height] or None
|
||||
self.is_nullable = opts.Extensions[meta_pb2.is_nullable]
|
||||
self.gui_type = opts.Extensions[meta_pb2.gui_type] or None
|
||||
self.gui_type = _enum_opt_name(opts, meta_pb2.gui_type)
|
||||
self.gui_flags = opts.Extensions[meta_pb2.gui_flags] or None
|
||||
self.enum_keys_map = opts.Extensions[meta_pb2.enum_keys_map_ref] or None
|
||||
self.no_cli = opts.Extensions[meta_pb2.no_cli]
|
||||
@@ -218,7 +231,7 @@ class FieldInfo:
|
||||
self.default_value = opts.Extensions[meta_pb2.default_value] if self.has_default else None
|
||||
self.enum_value_entries = list(opts.Extensions[meta_pb2.enum_value_entries])
|
||||
self.enum_label_entries = list(opts.Extensions[meta_pb2.enum_label_entries])
|
||||
self.co_type_hint = opts.Extensions[meta_pb2.co_type_hint] or None
|
||||
self.co_type_hint = _enum_opt_name(opts, meta_pb2.co_type_hint)
|
||||
|
||||
# Resolve C++ type info - co_type_hint overrides auto-detection
|
||||
co_type, option_class, is_vec = proto_type_to_co_type(
|
||||
@@ -578,6 +591,129 @@ class CodeGenerator:
|
||||
return str(val)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Lint pass — catch typos that protoc accepts but break the build or runtime.
|
||||
# protoc only validates proto-level correctness (field numbers, option types).
|
||||
# It has no idea that option strings get pasted into C++ L("...") literals, or
|
||||
# that a default must lie within [min_value, max_value]. These checks close that
|
||||
# gap so a bad edit fails fast at codegen time instead of at C++ compile / DLL
|
||||
# load / slice time.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# String options that the generator emits verbatim into C++ L("...") literals.
|
||||
_CPP_STRING_ATTRS = ("label", "full_label", "tooltip", "category", "sidetext")
|
||||
|
||||
_NUMERIC_SCALAR = {"coFloat", "coInt", "coPercent"}
|
||||
_NUMERIC_VECTOR = {"coFloats", "coInts", "coPercents"}
|
||||
_INT_TYPES = {"coInt", "coInts"}
|
||||
_BOOL_TYPES = {"coBool", "coBools"}
|
||||
|
||||
|
||||
def _has_unescaped_quote(s):
|
||||
"""True if the (proto-parsed) string contains a double-quote that is NOT
|
||||
backslash-escaped. Such a quote would terminate the generated C++ L("...")
|
||||
literal and break compilation. Mirrors how _escape_cpp passes strings
|
||||
through unchanged, so the proto must already carry '\\"' for a literal quote.
|
||||
"""
|
||||
if not s:
|
||||
return False
|
||||
t = s.replace('\\\\', '') # drop escaped backslashes so they don't mask a following quote
|
||||
t = t.replace('\\"', '') # drop already-escaped quotes
|
||||
return '"' in t
|
||||
|
||||
|
||||
# A plain C++ numeric literal: optional sign, digits/decimal, optional exponent,
|
||||
# optional float suffix (e.g. "200", "0.", "-5", "1.5e3", "60.0f"). Anything else
|
||||
# in default_value (identifiers, macros, "nil_value()", "{0.0}") is an intentional
|
||||
# C++ expression that the generator passes through verbatim — not range-checkable.
|
||||
_NUM_LIT = re.compile(r'^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?[fF]?$')
|
||||
|
||||
|
||||
def _num_tokens(dv):
|
||||
"""Split a default into comma-separated tokens. Returns (tokens, all_numeric)."""
|
||||
tokens = [t.strip() for t in dv.split(',') if t.strip() != ""]
|
||||
all_numeric = bool(tokens) and all(_NUM_LIT.match(t) for t in tokens)
|
||||
return tokens, all_numeric
|
||||
|
||||
|
||||
def _lint_default(field, errors):
|
||||
"""Validate a field's default_value against its type and numeric range.
|
||||
|
||||
Only plain numeric-literal defaults are checked; defaults that are C++
|
||||
expressions/constants are passed through by the generator and skipped here.
|
||||
"""
|
||||
dv = field.default_value
|
||||
name = field.name
|
||||
|
||||
if field.co_type in _NUMERIC_SCALAR or field.co_type in _NUMERIC_VECTOR:
|
||||
tokens, all_numeric = _num_tokens(dv)
|
||||
if not all_numeric:
|
||||
return # intentional C++ expression (e.g. macro, nil_value(), braced init)
|
||||
for tok in tokens:
|
||||
num = float(tok.rstrip('fF'))
|
||||
if field.co_type in _INT_TYPES and num != int(num):
|
||||
errors.append(f"{name}: default_value '{dv}' is not an integer for {field.co_type}")
|
||||
if field.min_value is not None and num < field.min_value:
|
||||
errors.append(f"{name}: default {tok} is below min_value {field.min_value}")
|
||||
if field.max_value is not None and num > field.max_value:
|
||||
errors.append(f"{name}: default {tok} is above max_value {field.max_value}")
|
||||
|
||||
elif field.co_type in _BOOL_TYPES:
|
||||
for tok in (t.strip().lower() for t in dv.split(',') if t.strip() != ""):
|
||||
# Only flag clear numeric mistakes; bare identifiers are C++ constants.
|
||||
if _NUM_LIT.match(tok) and tok not in ("0", "1"):
|
||||
errors.append(f"{name}: default_value token '{tok}' is not a valid bool for {field.co_type}")
|
||||
|
||||
|
||||
def lint_fields(fields):
|
||||
"""Return (errors, warnings) lists for the parsed fields.
|
||||
|
||||
Errors block code generation; warnings are advisory.
|
||||
"""
|
||||
errors = []
|
||||
warnings = []
|
||||
field_names = {f.name for f in fields}
|
||||
seen = set()
|
||||
|
||||
for f in fields:
|
||||
# Duplicate field name -> duplicate add() in generated C++ (redefinition).
|
||||
if f.name in seen:
|
||||
errors.append(f"{f.name}: duplicate field name across proto files")
|
||||
seen.add(f.name)
|
||||
|
||||
# min > max is always a mistake.
|
||||
if (f.min_value is not None and f.max_value is not None
|
||||
and f.min_value > f.max_value):
|
||||
errors.append(f"{f.name}: min_value ({f.min_value}) > max_value ({f.max_value})")
|
||||
|
||||
# Unescaped quotes in strings emitted into C++ L("...") break compilation.
|
||||
for attr in _CPP_STRING_ATTRS:
|
||||
val = getattr(f, attr)
|
||||
if val and _has_unescaped_quote(val):
|
||||
errors.append(f'{f.name}: ({attr}) has an unescaped double-quote — '
|
||||
f'use \\\\\\" in the proto for a literal quote')
|
||||
for el in f.enum_label_entries:
|
||||
if _has_unescaped_quote(el):
|
||||
errors.append(f"{f.name}: enum label '{el}' has an unescaped double-quote")
|
||||
|
||||
# coEnum with a keys map but no value entries can fail to deserialize unless
|
||||
# the keys map is supplied in C++ (see AGENTS.md). Advisory — some enums
|
||||
# legitimately source their values from a get_enum_values() keys map.
|
||||
if f.co_type == "coEnum" and f.enum_keys_map and not f.enum_value_entries:
|
||||
warnings.append(f"{f.name}: coEnum has (enum_keys_map_ref) but no (enum_value_entries) "
|
||||
f"— verify profile values deserialize (see AGENTS.md)")
|
||||
|
||||
# default_value type/range checks.
|
||||
if f.has_default and f.default_value:
|
||||
_lint_default(f, errors)
|
||||
|
||||
# ratio_over should point at a real key (advisory — may reference a virtual key).
|
||||
if f.ratio_over and f.ratio_over not in field_names:
|
||||
warnings.append(f"{f.name}: ratio_over references unknown key '{f.ratio_over}'")
|
||||
|
||||
return errors, warnings
|
||||
|
||||
|
||||
def _group_name_to_hook(name):
|
||||
"""Convert group name to a C++ hook method suffix: 'Cooling Fan' -> 'cooling_fan'."""
|
||||
return re.sub(r'[^a-z0-9]+', '_', name.lower()).strip('_')
|
||||
@@ -815,6 +951,8 @@ def main():
|
||||
help="Path to compiled .desc file (protoc --descriptor_set_out)")
|
||||
parser.add_argument("output_dir",
|
||||
help="Directory to write generated C++ files")
|
||||
parser.add_argument("--lint-only", action="store_true",
|
||||
help="Run proto lint checks and exit without writing files")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read descriptor set
|
||||
@@ -837,6 +975,21 @@ def main():
|
||||
# Generate code
|
||||
gen = CodeGenerator(file_descriptor_set)
|
||||
|
||||
# Lint before writing anything so a bad proto edit never produces broken
|
||||
# generated files (fails fast at codegen instead of C++ compile / runtime).
|
||||
errors, warnings = lint_fields(gen.fields)
|
||||
for w in warnings:
|
||||
print(f" LINT WARNING: {w}")
|
||||
if errors:
|
||||
print(f"\n*** Proto lint FAILED ({len(errors)} error(s)) ***")
|
||||
for e in errors:
|
||||
print(f" LINT ERROR: {e}")
|
||||
sys.exit(2)
|
||||
print(f"Lint passed ({len(gen.fields)} fields checked, {len(warnings)} warning(s))")
|
||||
|
||||
if args.lint_only:
|
||||
return
|
||||
|
||||
output_dir = Path(args.output_dir)
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# NO CHECKED-IN PROTOBUF GENCODE
|
||||
# source: config_metadata.proto
|
||||
# Protobuf Python Version: 6.32.1
|
||||
# Protobuf Python Version: 6.33.5
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
@@ -12,8 +12,8 @@ from google.protobuf.internal import builder as _builder
|
||||
_runtime_version.ValidateProtobufRuntimeVersion(
|
||||
_runtime_version.Domain.PUBLIC,
|
||||
6,
|
||||
32,
|
||||
1,
|
||||
33,
|
||||
5,
|
||||
'',
|
||||
'config_metadata.proto'
|
||||
)
|
||||
@@ -25,7 +25,7 @@ _sym_db = _symbol_database.Default()
|
||||
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x63onfig_metadata.proto\x12\x04orca\x1a google/protobuf/descriptor.proto\"0\n\x0e\x46loatOrPercent\x12\r\n\x05value\x18\x01 \x01(\x01\x12\x0f\n\x07percent\x18\x02 \x01(\x08\"\x1f\n\x07Point2D\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01*B\n\nConfigMode\x12\x0f\n\x0bMODE_SIMPLE\x10\x00\x12\x11\n\rMODE_ADVANCED\x10\x01\x12\x10\n\x0cMODE_DEVELOP\x10\x02*G\n\nPresetType\x12\x10\n\x0cPRESET_PRINT\x10\x00\x12\x13\n\x0fPRESET_FILAMENT\x10\x01\x12\x12\n\x0ePRESET_PRINTER\x10\x02*\xaa\x01\n\x10InvalidationStep\x12\x15\n\x11STEP_GCODE_EXPORT\x10\x00\x12\x13\n\x0fSTEP_SKIRT_BRIM\x10\x01\x12\x13\n\x0fSTEP_WIPE_TOWER\x10\x02\x12\x0e\n\nSTEP_SLICE\x10\x03\x12\x13\n\x0fSTEP_PERIMETERS\x10\x04\x12\x0f\n\x0bSTEP_INFILL\x10\x05\x12\x10\n\x0cSTEP_SUPPORT\x10\x06\x12\r\n\tSTEP_NONE\x10\x07*\x81\x01\n\x14OptionListMembership\x12\r\n\tLIST_NONE\x10\x00\x12\x1d\n\x19LIST_EXTRUDER_OPTION_KEYS\x10\x01\x12\x1d\n\x19LIST_FILAMENT_OPTION_KEYS\x10\x02\x12\x1c\n\x18LIST_VARIANT_OPTION_KEYS\x10\x03:.\n\x05label\x12\x1d.google.protobuf.FieldOptions\x18\xd1\x86\x03 \x01(\t:3\n\nfull_label\x12\x1d.google.protobuf.FieldOptions\x18\xd2\x86\x03 \x01(\t:0\n\x07tooltip\x12\x1d.google.protobuf.FieldOptions\x18\xd3\x86\x03 \x01(\t:1\n\x08\x63\x61tegory\x12\x1d.google.protobuf.FieldOptions\x18\xd4\x86\x03 \x01(\t:1\n\x08sidetext\x12\x1d.google.protobuf.FieldOptions\x18\xd5\x86\x03 \x01(\t:2\n\tmin_value\x12\x1d.google.protobuf.FieldOptions\x18\xd6\x86\x03 \x01(\x01:2\n\tmax_value\x12\x1d.google.protobuf.FieldOptions\x18\xd7\x86\x03 \x01(\x01:4\n\x0bmax_literal\x12\x1d.google.protobuf.FieldOptions\x18\xd8\x86\x03 \x01(\x01:?\n\x04mode\x12\x1d.google.protobuf.FieldOptions\x18\xd9\x86\x03 \x01(\x0e\x32\x10.orca.ConfigMode:3\n\nratio_over\x12\x1d.google.protobuf.FieldOptions\x18\xda\x86\x03 \x01(\t:2\n\tmultiline\x12\x1d.google.protobuf.FieldOptions\x18\xdd\x86\x03 \x01(\x08:3\n\nfull_width\x12\x1d.google.protobuf.FieldOptions\x18\xde\x86\x03 \x01(\x08:/\n\x06height\x12\x1d.google.protobuf.FieldOptions\x18\xdf\x86\x03 \x01(\x05:A\n\x06preset\x12\x1d.google.protobuf.FieldOptions\x18\xdb\x86\x03 \x01(\x0e\x32\x10.orca.PresetType:L\n\x0binvalidates\x12\x1d.google.protobuf.FieldOptions\x18\xdc\x86\x03 \x03(\x0e\x32\x16.orca.InvalidationStep:T\n\x0flist_membership\x12\x1d.google.protobuf.FieldOptions\x18\xe2\x86\x03 \x03(\x0e\x32\x1a.orca.OptionListMembership:4\n\x0blegacy_name\x12\x1d.google.protobuf.FieldOptions\x18\xe0\x86\x03 \x01(\t:4\n\x0bis_nullable\x12\x1d.google.protobuf.FieldOptions\x18\xe1\x86\x03 \x01(\x08:1\n\x08gui_type\x12\x1d.google.protobuf.FieldOptions\x18\xe3\x86\x03 \x01(\t:2\n\tgui_flags\x12\x1d.google.protobuf.FieldOptions\x18\xe4\x86\x03 \x01(\t::\n\x11\x65num_keys_map_ref\x12\x1d.google.protobuf.FieldOptions\x18\xe5\x86\x03 \x01(\t:/\n\x06no_cli\x12\x1d.google.protobuf.FieldOptions\x18\xe6\x86\x03 \x01(\x08:1\n\x08readonly\x12\x1d.google.protobuf.FieldOptions\x18\xe7\x86\x03 \x01(\x08:5\n\x0c\x63o_type_hint\x12\x1d.google.protobuf.FieldOptions\x18\xe8\x86\x03 \x01(\t:6\n\rdefault_value\x12\x1d.google.protobuf.FieldOptions\x18\xe9\x86\x03 \x01(\t:4\n\x0bhas_default\x12\x1d.google.protobuf.FieldOptions\x18\xec\x86\x03 \x01(\x08:;\n\x12\x65num_value_entries\x12\x1d.google.protobuf.FieldOptions\x18\xea\x86\x03 \x03(\t:;\n\x12\x65num_label_entries\x12\x1d.google.protobuf.FieldOptions\x18\xeb\x86\x03 \x03(\t:1\n\x08tab_type\x12\x1d.google.protobuf.FieldOptions\x18\xed\x86\x03 \x01(\t:1\n\x08tab_page\x12\x1d.google.protobuf.FieldOptions\x18\xee\x86\x03 \x01(\t:5\n\x0ctab_optgroup\x12\x1d.google.protobuf.FieldOptions\x18\xef\x86\x03 \x01(\t:>\n\x13virtual_preset_keys\x12\x1f.google.protobuf.MessageOptions\x18\xe1\xd4\x03 \x03(\tb\x06proto3')
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x63onfig_metadata.proto\x12\x04orca\x1a google/protobuf/descriptor.proto\"0\n\x0e\x46loatOrPercent\x12\r\n\x05value\x18\x01 \x01(\x01\x12\x0f\n\x07percent\x18\x02 \x01(\x08\"\x1f\n\x07Point2D\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01*B\n\nConfigMode\x12\x0f\n\x0bMODE_SIMPLE\x10\x00\x12\x11\n\rMODE_ADVANCED\x10\x01\x12\x10\n\x0cMODE_DEVELOP\x10\x02*G\n\nPresetType\x12\x10\n\x0cPRESET_PRINT\x10\x00\x12\x13\n\x0fPRESET_FILAMENT\x10\x01\x12\x12\n\x0ePRESET_PRINTER\x10\x02*\xaa\x01\n\x10InvalidationStep\x12\x15\n\x11STEP_GCODE_EXPORT\x10\x00\x12\x13\n\x0fSTEP_SKIRT_BRIM\x10\x01\x12\x13\n\x0fSTEP_WIPE_TOWER\x10\x02\x12\x0e\n\nSTEP_SLICE\x10\x03\x12\x13\n\x0fSTEP_PERIMETERS\x10\x04\x12\x0f\n\x0bSTEP_INFILL\x10\x05\x12\x10\n\x0cSTEP_SUPPORT\x10\x06\x12\r\n\tSTEP_NONE\x10\x07*\x81\x01\n\x14OptionListMembership\x12\r\n\tLIST_NONE\x10\x00\x12\x1d\n\x19LIST_EXTRUDER_OPTION_KEYS\x10\x01\x12\x1d\n\x19LIST_FILAMENT_OPTION_KEYS\x10\x02\x12\x1c\n\x18LIST_VARIANT_OPTION_KEYS\x10\x03*\\\n\nCoTypeHint\x12\x16\n\x12\x43O_TYPE_HINT_UNSET\x10\x00\x12\r\n\tcoPercent\x10\x01\x12\x0e\n\ncoPercents\x10\x02\x12\n\n\x06\x63oEnum\x10\x03\x12\x0b\n\x07\x63oEnums\x10\x04*\x83\x01\n\x07GuiType\x12\x12\n\x0eGUI_TYPE_UNSET\x10\x00\x12\x0f\n\x0bi_enum_open\x10\x01\x12\x0f\n\x0b\x66_enum_open\x10\x02\x12\t\n\x05\x63olor\x10\x03\x12\x0f\n\x0bselect_open\x10\x04\x12\n\n\x06slider\x10\x05\x12\n\n\x06legend\x10\x06\x12\x0e\n\none_string\x10\x07:.\n\x05label\x12\x1d.google.protobuf.FieldOptions\x18\xd1\x86\x03 \x01(\t:3\n\nfull_label\x12\x1d.google.protobuf.FieldOptions\x18\xd2\x86\x03 \x01(\t:0\n\x07tooltip\x12\x1d.google.protobuf.FieldOptions\x18\xd3\x86\x03 \x01(\t:1\n\x08\x63\x61tegory\x12\x1d.google.protobuf.FieldOptions\x18\xd4\x86\x03 \x01(\t:1\n\x08sidetext\x12\x1d.google.protobuf.FieldOptions\x18\xd5\x86\x03 \x01(\t:2\n\tmin_value\x12\x1d.google.protobuf.FieldOptions\x18\xd6\x86\x03 \x01(\x01:2\n\tmax_value\x12\x1d.google.protobuf.FieldOptions\x18\xd7\x86\x03 \x01(\x01:4\n\x0bmax_literal\x12\x1d.google.protobuf.FieldOptions\x18\xd8\x86\x03 \x01(\x01:?\n\x04mode\x12\x1d.google.protobuf.FieldOptions\x18\xd9\x86\x03 \x01(\x0e\x32\x10.orca.ConfigMode:3\n\nratio_over\x12\x1d.google.protobuf.FieldOptions\x18\xda\x86\x03 \x01(\t:2\n\tmultiline\x12\x1d.google.protobuf.FieldOptions\x18\xdd\x86\x03 \x01(\x08:3\n\nfull_width\x12\x1d.google.protobuf.FieldOptions\x18\xde\x86\x03 \x01(\x08:/\n\x06height\x12\x1d.google.protobuf.FieldOptions\x18\xdf\x86\x03 \x01(\x05:A\n\x06preset\x12\x1d.google.protobuf.FieldOptions\x18\xdb\x86\x03 \x01(\x0e\x32\x10.orca.PresetType:L\n\x0binvalidates\x12\x1d.google.protobuf.FieldOptions\x18\xdc\x86\x03 \x03(\x0e\x32\x16.orca.InvalidationStep:T\n\x0flist_membership\x12\x1d.google.protobuf.FieldOptions\x18\xe2\x86\x03 \x03(\x0e\x32\x1a.orca.OptionListMembership:4\n\x0blegacy_name\x12\x1d.google.protobuf.FieldOptions\x18\xe0\x86\x03 \x01(\t:4\n\x0bis_nullable\x12\x1d.google.protobuf.FieldOptions\x18\xe1\x86\x03 \x01(\x08:@\n\x08gui_type\x12\x1d.google.protobuf.FieldOptions\x18\xe3\x86\x03 \x01(\x0e\x32\r.orca.GuiType:2\n\tgui_flags\x12\x1d.google.protobuf.FieldOptions\x18\xe4\x86\x03 \x01(\t::\n\x11\x65num_keys_map_ref\x12\x1d.google.protobuf.FieldOptions\x18\xe5\x86\x03 \x01(\t:/\n\x06no_cli\x12\x1d.google.protobuf.FieldOptions\x18\xe6\x86\x03 \x01(\x08:1\n\x08readonly\x12\x1d.google.protobuf.FieldOptions\x18\xe7\x86\x03 \x01(\x08:G\n\x0c\x63o_type_hint\x12\x1d.google.protobuf.FieldOptions\x18\xe8\x86\x03 \x01(\x0e\x32\x10.orca.CoTypeHint:6\n\rdefault_value\x12\x1d.google.protobuf.FieldOptions\x18\xe9\x86\x03 \x01(\t:4\n\x0bhas_default\x12\x1d.google.protobuf.FieldOptions\x18\xec\x86\x03 \x01(\x08:;\n\x12\x65num_value_entries\x12\x1d.google.protobuf.FieldOptions\x18\xea\x86\x03 \x03(\t:;\n\x12\x65num_label_entries\x12\x1d.google.protobuf.FieldOptions\x18\xeb\x86\x03 \x03(\t:1\n\x08tab_type\x12\x1d.google.protobuf.FieldOptions\x18\xed\x86\x03 \x01(\t:1\n\x08tab_page\x12\x1d.google.protobuf.FieldOptions\x18\xee\x86\x03 \x01(\t:5\n\x0ctab_optgroup\x12\x1d.google.protobuf.FieldOptions\x18\xef\x86\x03 \x01(\t:>\n\x13virtual_preset_keys\x12\x1f.google.protobuf.MessageOptions\x18\xe1\xd4\x03 \x03(\tb\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
@@ -40,6 +40,10 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
||||
_globals['_INVALIDATIONSTEP']._serialized_end=460
|
||||
_globals['_OPTIONLISTMEMBERSHIP']._serialized_start=463
|
||||
_globals['_OPTIONLISTMEMBERSHIP']._serialized_end=592
|
||||
_globals['_COTYPEHINT']._serialized_start=594
|
||||
_globals['_COTYPEHINT']._serialized_end=686
|
||||
_globals['_GUITYPE']._serialized_start=689
|
||||
_globals['_GUITYPE']._serialized_end=820
|
||||
_globals['_FLOATORPERCENT']._serialized_start=65
|
||||
_globals['_FLOATORPERCENT']._serialized_end=113
|
||||
_globals['_POINT2D']._serialized_start=115
|
||||
|
||||
@@ -87,6 +87,12 @@ def step_generate():
|
||||
str(DESC_FILE), str(CODEGEN_OUT)])
|
||||
|
||||
|
||||
def step_lint():
|
||||
print("\n=== Lint: proto sanity checks ===")
|
||||
return run([sys.executable, str(ROOT / "tools" / "config_codegen.py"),
|
||||
str(DESC_FILE), str(CODEGEN_OUT), "--lint-only"])
|
||||
|
||||
|
||||
def step_validate():
|
||||
print("\n=== Step 3: Validate ===")
|
||||
return run([sys.executable, str(ROOT / "tools" / "validate_codegen.py")])
|
||||
@@ -101,7 +107,8 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.validate_only:
|
||||
sys.exit(0 if step_validate() else 1)
|
||||
# Compile + lint the protos, then check the committed generated files are current.
|
||||
sys.exit(0 if (step_compile() and step_lint() and step_validate()) else 1)
|
||||
|
||||
for name, fn in [("Compile", step_compile), ("Generate", step_generate)]:
|
||||
if not fn():
|
||||
|
||||
Reference in New Issue
Block a user