1 //
2 // Copyright (C) 2022 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "codegen_java.h"
18
19 #include <expresscatalog-utils.h>
20 #include <stdio.h>
21
22 namespace android {
23 namespace express {
24
writeJavaFilePreamble(FILE * fd)25 void writeJavaFilePreamble(FILE* fd) {
26 fprintf(fd, "// DO NOT EDIT THIS FILE\n");
27 fprintf(fd, "// This is auto-generated file by expresscatalog-codegen\n\n");
28 }
29
writeJavaPackagePreamble(FILE * fd,const std::string & packageName)30 void writeJavaPackagePreamble(FILE* fd, const std::string& packageName) {
31 fprintf(fd, "package %s;\n\n", packageName.c_str());
32
33 fprintf(fd, "import android.util.ArrayMap;\n\n");
34 fprintf(fd, "import java.util.InputMismatchException;\n\n");
35 }
36
getMetricTypeString(int metricType)37 const char* getMetricTypeString(int metricType) {
38 static const char* metricTypeStringMap[] = {
39 "METRIC_TYPE_UNKNOWN",
40 "METRIC_TYPE_COUNTER",
41 "METRIC_TYPE_HISTOGRAM",
42 "METRIC_TYPE_COUNTER_WITH_UID",
43 "METRIC_TYPE_HISTOGRAM_WITH_UID",
44 };
45
46 if (metricType == 0) {
47 return nullptr;
48 }
49
50 return metricTypeStringMap[metricType];
51 }
52
writeJavaHashMapInitFunction(FILE * fd,const MetricInfoMap & metricsIds)53 void writeJavaHashMapInitFunction(FILE* fd, const MetricInfoMap& metricsIds) {
54 fprintf(fd, "private static ArrayMap<String, MetricInfo> metricIds;\n");
55 fprintf(fd, "static {\n");
56 fprintf(fd, " metricIds = new ArrayMap<String, MetricInfo>();\n");
57 for (const auto& metricInfo : metricsIds) {
58 const char* metricTypeString = getMetricTypeString(metricInfo.second.type);
59 if (metricTypeString != nullptr) {
60 fprintf(fd, " metricIds.put(\"%s\", new MetricInfo(%ldl, %s));\n",
61 metricInfo.first.c_str(), metricInfo.second.hash, metricTypeString);
62 } else {
63 LOGE("Metric type is undefined for %s. Termination\n", metricInfo.first.c_str());
64 exit(-1);
65 }
66 }
67 fprintf(fd, "}\n\n");
68 }
69
generateCodeImpl(FILE * fd,const MetricInfoMap & metricsIds) const70 bool CodeGeneratorJava::generateCodeImpl(FILE* fd, const MetricInfoMap& metricsIds) const {
71 writeJavaFilePreamble(fd);
72 writeJavaPackagePreamble(fd, mPackageName);
73
74 fprintf(fd, "public final class %s {\n\n", mClassName.c_str());
75
76 // TODO: auto-generate enum int constants
77 fprintf(fd, "public static final int METRIC_TYPE_UNKNOWN = 0;\n");
78 fprintf(fd, "public static final int METRIC_TYPE_COUNTER = 1;\n");
79 fprintf(fd, "public static final int METRIC_TYPE_HISTOGRAM = 2;\n");
80 fprintf(fd, "public static final int METRIC_TYPE_COUNTER_WITH_UID = 3;\n");
81 fprintf(fd, "public static final int METRIC_TYPE_HISTOGRAM_WITH_UID = 4;\n\n");
82
83 fprintf(fd, "private static final class MetricInfo {\n");
84 fprintf(fd, " MetricInfo(long hash, int type) {\n");
85 fprintf(fd, " mHash = hash;\n");
86 fprintf(fd, " mType = type;\n");
87 fprintf(fd, " }\n");
88 fprintf(fd, " public long mHash;\n");
89 fprintf(fd, " public int mType;\n");
90 fprintf(fd, "}\n\n");
91
92 writeJavaHashMapInitFunction(fd, metricsIds);
93
94 fprintf(fd, "static long getMetricIdHash(String metricId, int type) {\n");
95 fprintf(fd, " MetricInfo info = metricIds.get(metricId);\n");
96 fprintf(fd, " if(info == null) {\n");
97 fprintf(fd,
98 " throw new IllegalArgumentException(\"Metric is undefined \" + metricId);\n");
99 fprintf(fd, " }\n");
100 fprintf(fd, " if(info.mType != type) {\n");
101 fprintf(fd, " throw new InputMismatchException(\"Metric type is not \" + type);\n");
102 fprintf(fd, " }\n");
103 fprintf(fd, " return info.mHash;\n");
104 fprintf(fd, "}\n\n");
105
106 fprintf(fd, "}\n\n");
107
108 return true;
109 }
110
111 } // namespace express
112 } // namespace android
113