// // Copyright (C) 2022 The Android Open Source Project // // 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. // #include "codegen_java.h" #include #include namespace android { namespace express { void writeJavaFilePreamble(FILE* fd) { fprintf(fd, "// DO NOT EDIT THIS FILE\n"); fprintf(fd, "// This is auto-generated file by expresscatalog-codegen\n\n"); } void writeJavaPackagePreamble(FILE* fd, const std::string& packageName) { fprintf(fd, "package %s;\n\n", packageName.c_str()); fprintf(fd, "import android.util.ArrayMap;\n\n"); fprintf(fd, "import java.util.InputMismatchException;\n\n"); } const char* getMetricTypeString(int metricType) { static const char* metricTypeStringMap[] = { "METRIC_TYPE_UNKNOWN", "METRIC_TYPE_COUNTER", "METRIC_TYPE_HISTOGRAM", "METRIC_TYPE_COUNTER_WITH_UID", "METRIC_TYPE_HISTOGRAM_WITH_UID", }; if (metricType == 0) { return nullptr; } return metricTypeStringMap[metricType]; } void writeJavaHashMapInitFunction(FILE* fd, const MetricInfoMap& metricsIds) { fprintf(fd, "private static ArrayMap metricIds;\n"); fprintf(fd, "static {\n"); fprintf(fd, " metricIds = new ArrayMap();\n"); for (const auto& metricInfo : metricsIds) { const char* metricTypeString = getMetricTypeString(metricInfo.second.type); if (metricTypeString != nullptr) { fprintf(fd, " metricIds.put(\"%s\", new MetricInfo(%ldl, %s));\n", metricInfo.first.c_str(), metricInfo.second.hash, metricTypeString); } else { LOGE("Metric type is undefined for %s. Termination\n", metricInfo.first.c_str()); exit(-1); } } fprintf(fd, "}\n\n"); } bool CodeGeneratorJava::generateCodeImpl(FILE* fd, const MetricInfoMap& metricsIds) const { writeJavaFilePreamble(fd); writeJavaPackagePreamble(fd, mPackageName); fprintf(fd, "public final class %s {\n\n", mClassName.c_str()); // TODO: auto-generate enum int constants fprintf(fd, "public static final int METRIC_TYPE_UNKNOWN = 0;\n"); fprintf(fd, "public static final int METRIC_TYPE_COUNTER = 1;\n"); fprintf(fd, "public static final int METRIC_TYPE_HISTOGRAM = 2;\n"); fprintf(fd, "public static final int METRIC_TYPE_COUNTER_WITH_UID = 3;\n"); fprintf(fd, "public static final int METRIC_TYPE_HISTOGRAM_WITH_UID = 4;\n\n"); fprintf(fd, "private static final class MetricInfo {\n"); fprintf(fd, " MetricInfo(long hash, int type) {\n"); fprintf(fd, " mHash = hash;\n"); fprintf(fd, " mType = type;\n"); fprintf(fd, " }\n"); fprintf(fd, " public long mHash;\n"); fprintf(fd, " public int mType;\n"); fprintf(fd, "}\n\n"); writeJavaHashMapInitFunction(fd, metricsIds); fprintf(fd, "static long getMetricIdHash(String metricId, int type) {\n"); fprintf(fd, " MetricInfo info = metricIds.get(metricId);\n"); fprintf(fd, " if(info == null) {\n"); fprintf(fd, " throw new IllegalArgumentException(\"Metric is undefined \" + metricId);\n"); fprintf(fd, " }\n"); fprintf(fd, " if(info.mType != type) {\n"); fprintf(fd, " throw new InputMismatchException(\"Metric type is not \" + type);\n"); fprintf(fd, " }\n"); fprintf(fd, " return info.mHash;\n"); fprintf(fd, "}\n\n"); fprintf(fd, "}\n\n"); return true; } } // namespace express } // namespace android