# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from __future__ import absolute_import, division, print_function, unicode_literals import os ENUMS = { "Direction": ["Inherit", "LTR", "RTL"], "Unit": ["Undefined", "Point", "Percent", "Auto"], "FlexDirection": ["Column", "ColumnReverse", "Row", "RowReverse"], "Justify": [ "FlexStart", "Center", "FlexEnd", "SpaceBetween", "SpaceAround", "SpaceEvenly", ], "Overflow": ["Visible", "Hidden", "Scroll"], "Align": [ "Auto", "FlexStart", "Center", "FlexEnd", "Stretch", "Baseline", "SpaceBetween", "SpaceAround", ], "PositionType": ["Static", "Relative", "Absolute"], "Display": ["Flex", "None"], "Wrap": ["NoWrap", "Wrap", "WrapReverse"], "MeasureMode": ["Undefined", "Exactly", "AtMost"], "Dimension": ["Width", "Height"], "Edge": [ "Left", "Top", "Right", "Bottom", "Start", "End", "Horizontal", "Vertical", "All", ], "NodeType": ["Default", "Text"], "LogLevel": ["Error", "Warn", "Info", "Debug", "Verbose", "Fatal"], "ExperimentalFeature": [ # Mimic web flex-basis behavior (experiment may be broken) "WebFlexBasis", # Conformance fix: https://github.com/facebook/yoga/pull/1028 "AbsolutePercentageAgainstPaddingEdge", # Conformance fix: https://github.com/facebook/yoga/pull/1028 "FixAbsoluteTrailingColumnMargin", ], "PrintOptions": [("Layout", 1), ("Style", 2), ("Children", 4)], "Gutter": ["Column", "Row", "All"], } # Generated Java enums used to emit @DoNotStrip, but D17519844 removed them # manually from all but YogaLogLevel. TODO: Is it safe to remove from it as # well? DO_NOT_STRIP = ["LogLevel"] def get_license(ext): prologue = "/**" if ext == "js" else "/*" return """{} * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // @{} by enums.py """.format( prologue, "generated" ) def to_java_upper(symbol): symbol = str(symbol) out = "" for i in range(0, len(symbol)): c = symbol[i] if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]): out += "_" out += c.upper() return out def to_log_lower(symbol): symbol = str(symbol) out = "" for i in range(0, len(symbol)): c = symbol[i] if str.istitle(c) and i is not 0 and not str.istitle(symbol[i - 1]): out += "-" out += c.lower() return out root = os.path.dirname(os.path.abspath(__file__)) # write out C & Objective-C headers with open(root + "/yoga/YGEnums.h", "w") as f: f.write(get_license("cpp")) f.write("#pragma once\n") f.write('#include "YGMacros.h"\n\n') f.write("// clang-format off\n\n\n") f.write("YG_EXTERN_C_BEGIN\n\n") items = sorted(ENUMS.items()) for name, values in items: if isinstance(values[0], tuple): f.write("YG_ENUM_DECL(\n") else: f.write("YG_ENUM_SEQ_DECL(\n") f.write(" YG%s,\n" % name) for value in values: if isinstance(value, tuple): f.write(" YG%s%s = %d" % (name, value[0], value[1])) else: f.write(" YG%s%s" % (name, value)) if value == values[-1]: f.write(")\n") else: f.write(",\n") f.write("\n") f.write("YG_EXTERN_C_END\n") # write out C body for printing with open(root + "/yoga/YGEnums.cpp", "w") as f: f.write(get_license("cpp")) f.write('#include "YGEnums.h"\n\n') items = sorted(ENUMS.items()) for name, values in items: f.write("const char* YG%sToString(const YG%s value) {\n" % (name, name)) f.write(" switch (value) {\n") for value in values: if isinstance(value, tuple): f.write(" case YG%s%s:\n" % (name, value[0])) f.write(' return "%s";\n' % to_log_lower(value[0])) else: f.write(" case YG%s%s:\n" % (name, value)) f.write(' return "%s";\n' % to_log_lower(value)) f.write(" }\n") f.write(' return "unknown";\n') f.write("}\n") if name != items[-1][0]: f.write("\n") # write out java files for name, values in sorted(ENUMS.items()): with open(root + "/java/com/facebook/yoga/Yoga%s.java" % name, "w") as f: f.write(get_license("java")) f.write("package com.facebook.yoga;\n\n") if name in DO_NOT_STRIP: f.write("import com.facebook.yoga.annotations.DoNotStrip;\n\n") f.write("@DoNotStrip\n") f.write("public enum Yoga%s {\n" % name) if len(values) > 0: for value in values: if isinstance(value, tuple): f.write(" %s(%d)" % (to_java_upper(value[0]), value[1])) else: f.write(" %s(%d)" % (to_java_upper(value), values.index(value))) if values.index(value) is len(values) - 1: f.write(";\n") else: f.write(",\n") else: f.write("__EMPTY(-1);") f.write("\n") f.write(" private final int mIntValue;\n") f.write("\n") f.write(" Yoga%s(int intValue) {\n" % name) f.write(" mIntValue = intValue;\n") f.write(" }\n") f.write("\n") f.write(" public int intValue() {\n") f.write(" return mIntValue;\n") f.write(" }\n") f.write("\n") if name in DO_NOT_STRIP: f.write(" @DoNotStrip\n") f.write(" public static Yoga%s fromInt(int value) {\n" % name) f.write(" switch (value) {\n") for value in values: if isinstance(value, tuple): f.write( " case %d: return %s;\n" % (value[1], to_java_upper(value[0])) ) else: f.write( " case %d: return %s;\n" % (values.index(value), to_java_upper(value)) ) f.write( ' default: throw new IllegalArgumentException("Unknown enum value: " + value);\n' ) f.write(" }\n") f.write(" }\n") f.write("}\n") # write out csharp files for name, values in sorted(ENUMS.items()): with open(root + "/csharp/Facebook.Yoga/Yoga%s.cs" % name, "w") as f: f.write(get_license("cs")) f.write("namespace Facebook.Yoga\n{\n") if isinstance(next(iter(values or []), None), tuple): f.write(" [System.Flags]\n") f.write(" public enum Yoga%s\n {\n" % name) for value in values: if isinstance(value, tuple): f.write(" %s = %d,\n" % (value[0], value[1])) else: f.write(" %s,\n" % value) f.write(" }\n") f.write("}\n") # write out javascript file with open(root + "/javascript/src_js/generated/YGEnums.js", "w") as f: f.write(get_license("js")) f.write("module.exports = {\n") items = sorted(ENUMS.items()) for name, values in items: base = 0 for value in values: value_arg = value[0] if isinstance(value, tuple) else value ordinal_arg = value[1] if isinstance(value, tuple) else base f.write( " %s_%s: %d,\n" % (to_java_upper(name), to_java_upper(value_arg), ordinal_arg) ) base = ordinal_arg + 1 if name != items[-1][0]: f.write("\n") f.write("};\n") with open(root + "/javascript/src_js/generated/YGEnums.d.ts", "w") as f: f.write(get_license("js")) for name, values in sorted(ENUMS.items()): base = 0 for value in values: value_arg = value[0] if isinstance(value, tuple) else value ordinal_arg = value[1] if isinstance(value, tuple) else base f.write( ( "type {name}_{value} = {ordinal} & ['{name}']\n" + "export const {name}_{value}: {name}_{value};\n\n" ).format( name=to_java_upper(name), value=to_java_upper(value_arg), ordinal=ordinal_arg, ) ) base = ordinal_arg + 1 f.write("\n") for name, values in sorted(ENUMS.items()): f.write("export type {} =\n".format(name)) for value in values: unpackedValue = value[0] if isinstance(value, tuple) else value f.write( " | typeof {}_{}".format( to_java_upper(name), to_java_upper(unpackedValue) ) ) if values[-1] == value: f.write(";\n") else: f.write("\n") f.write("\n")