diff --git a/code-generator/pom.xml b/code-generator/pom.xml index ad623f1..9e33b25 100644 --- a/code-generator/pom.xml +++ b/code-generator/pom.xml @@ -41,11 +41,6 @@ slf4j-api - - com.google.guava - guava - - org.jboss.forge.roaster roaster-api diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java index 5689d1b..c8f4a2a 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoGenerator.java @@ -15,7 +15,6 @@ */ package io.streamnative.lightproto.generator; -import com.google.common.base.Joiner; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; import org.slf4j.Logger; @@ -79,7 +78,7 @@ public static List generate(List descriptors, File ou String outerClassName = Util.camelCaseFirstUpper(classPrefix, fileWithoutExtension); String javaPackageName = proto.getJavaPackageName(); - String javaDir = Joiner.on('/').join(javaPackageName.split("\\.")); + String javaDir = String.join("/", javaPackageName.split("\\.")); Path targetDir = Paths.get(String.format("%s/%s", outputDirectory, javaDir)); LightProto lightProto = new LightProto(proto, fileName, outerClassName, useOuterClass, generateTextFormat, generateJson); @@ -94,7 +93,7 @@ public static List generate(List descriptors, File ou JavaClassSource codecClass = (JavaClassSource) Roaster.parse(is); codecClass.setPackage(javaPackage); - String javaDir = Joiner.on('/').join(javaPackage.split("\\.")); + String javaDir = String.join("/", javaPackage.split("\\.")); Path codecFile = Paths.get(String.format("%s/%s/LightProtoCodec.java", outputDirectory, javaDir)); try (Writer w = Files.newBufferedWriter(codecFile)) { w.write(String.format( diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoNumberField.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoNumberField.java index b0242dc..da164db 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoNumberField.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/LightProtoNumberField.java @@ -15,9 +15,8 @@ */ package io.streamnative.lightproto.generator; -import com.google.common.collect.Maps; - import java.io.PrintWriter; +import java.util.HashMap; import java.util.Map; import static io.streamnative.lightproto.generator.Util.camelCase; @@ -25,7 +24,7 @@ public class LightProtoNumberField extends LightProtoField { - private static final Map typeToTag = Maps.newHashMap(); + private static final Map typeToTag = new HashMap<>(); static { typeToTag.put("double", "LightProtoCodec.WIRETYPE_FIXED64"); diff --git a/code-generator/src/main/java/io/streamnative/lightproto/generator/Util.java b/code-generator/src/main/java/io/streamnative/lightproto/generator/Util.java index 1c407cf..ff7b453 100644 --- a/code-generator/src/main/java/io/streamnative/lightproto/generator/Util.java +++ b/code-generator/src/main/java/io/streamnative/lightproto/generator/Util.java @@ -17,9 +17,6 @@ import java.io.PrintWriter; -import static com.google.common.base.CaseFormat.LOWER_CAMEL; -import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE; - public class Util { public static String camelCase(String... parts) { @@ -30,7 +27,7 @@ public static String camelCase(String... parts) { continue; } if (s.contains("_")) { - s = LOWER_UNDERSCORE.to(LOWER_CAMEL, s); + s = lowerUnderscoreToLowerCamel(s); } if (i != 0) { @@ -52,7 +49,7 @@ public static String camelCaseFirstUpper(String... parts) { public static String upperCase(String... parts) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < parts.length; i++) { - String s = LOWER_CAMEL.to(LOWER_UNDERSCORE, parts[i]); + String s = lowerCamelToLowerUnderscore(parts[i]); if (i != 0) { sb.append('_'); } @@ -63,6 +60,48 @@ public static String upperCase(String... parts) { return sb.toString().toUpperCase(); } + // Mirrors Guava's CaseFormat.LOWER_UNDERSCORE.to(LOWER_CAMEL, s): + // splits on '_', lowercases everything, capitalizes the first char of + // each non-leading segment. + static String lowerUnderscoreToLowerCamel(String s) { + if (s.indexOf('_') < 0) { + return s; + } + StringBuilder sb = new StringBuilder(s.length()); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + } else if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(Character.toLowerCase(c)); + } + } + return sb.toString(); + } + + // Mirrors Guava's CaseFormat.LOWER_CAMEL.to(LOWER_UNDERSCORE, s): + // inserts '_' before every uppercase letter (except a leading one) and + // lowercases all letters. + static String lowerCamelToLowerUnderscore(String s) { + StringBuilder sb = new StringBuilder(s.length() + 4); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isUpperCase(c)) { + if (i > 0) { + sb.append('_'); + } + sb.append(Character.toLowerCase(c)); + } else { + sb.append(c); + } + } + return sb.toString(); + } + // pluralize/singular rules vendored from JiBX NameUtilities // (Copyright (c) 2008-2010, Dennis M. Sosnoski, BSD 3-clause license). public static String plural(String name) { diff --git a/code-generator/src/test/java/io/streamnative/lightproto/generator/UtilTest.java b/code-generator/src/test/java/io/streamnative/lightproto/generator/UtilTest.java index f63fbaa..7e8b7c7 100644 --- a/code-generator/src/test/java/io/streamnative/lightproto/generator/UtilTest.java +++ b/code-generator/src/test/java/io/streamnative/lightproto/generator/UtilTest.java @@ -63,6 +63,55 @@ void pluralizes(String input, String expected) { assertEquals(expected, Util.plural(input)); } + @ParameterizedTest + @CsvSource({ + // typical snake_case + "first_name, firstName", + "user_id, userId", + "foo_bar_baz, fooBarBaz", + "snake_case_name, snakeCaseName", + // no underscore: returned as-is (does NOT lowercase) + "foo, foo", + "MyService, MyService", + // numerics + "abc_123, abc123", + // double underscore + "foo__bar, fooBar", + // leading underscore capitalizes the next char + "_leading, Leading", + "_msgSize, Msgsize", + // trailing underscore is dropped + "trailing_, trailing", + // embedded uppercase is normalized to lowercase (matches Guava) + "ALL_CAPS, allCaps", + "Foo_Bar, fooBar", + "FOO_BAR_BAZ, fooBarBaz", + }) + void snakeToCamel(String input, String expected) { + assertEquals(expected, Util.lowerUnderscoreToLowerCamel(input)); + } + + @ParameterizedTest + @CsvSource({ + // typical camelCase + "fooBar, foo_bar", + "fooBarBaz, foo_bar_baz", + "myService, my_service", + // leading uppercase: lowercased without leading underscore + "MyService, my_service", + "X, x", + // no uppercase: unchanged + "foo, foo", + "first_name, first_name", + // numerics + "abc123, abc123", + // already snake-ish stays put + "foo_bar_baz, foo_bar_baz", + }) + void camelToSnake(String input, String expected) { + assertEquals(expected, Util.lowerCamelToLowerUnderscore(input)); + } + @ParameterizedTest @CsvSource({ // ends with 'ies': replace with 'y' diff --git a/pom.xml b/pom.xml index ce61a10..10f5ad6 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,6 @@ 1.7.25 5.7.0 - 32.0.0-jre 4.1.131.Final 2.22.2.Final 1.68.0 @@ -158,11 +157,6 @@ slf4j-api ${slf4j.version} - - com.google.guava - guava - ${guava.version} - io.netty netty-bom