From 11cb1a3d8f23896c1aaf7399719c87c8b84ff0a7 Mon Sep 17 00:00:00 2001 From: Mira Leung Date: Mon, 15 Jun 2020 20:35:46 +0000 Subject: [PATCH] feat: add Value interface and PrimitiveValue set-up --- .../generator/engine/ast/PrimitiveValue.java | 79 +++++++++++++++++++ .../api/generator/engine/ast/Value.java | 17 ++++ .../api/generator/engine/ast/BUILD.bazel | 1 + .../engine/ast/PrimitiveValueTest.java | 64 +++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 src/main/java/com/google/api/generator/engine/ast/PrimitiveValue.java create mode 100644 src/main/java/com/google/api/generator/engine/ast/Value.java create mode 100644 src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java diff --git a/src/main/java/com/google/api/generator/engine/ast/PrimitiveValue.java b/src/main/java/com/google/api/generator/engine/ast/PrimitiveValue.java new file mode 100644 index 0000000000..cb168d087c --- /dev/null +++ b/src/main/java/com/google/api/generator/engine/ast/PrimitiveValue.java @@ -0,0 +1,79 @@ +// Copyright 2020 Google LLC +// +// 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. + +package com.google.api.generator.engine.ast; + +import com.google.api.generator.engine.lexicon.Literal; +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class PrimitiveValue implements Value { + static class TypeMismatchException extends RuntimeException { + public TypeMismatchException(String errorMessage) { + super(errorMessage); + } + } + + // TODO(miraleung):F Handle object types. + public abstract TypeNode type(); + + public abstract String value(); + + public static Builder builder() { + return new AutoValue_PrimitiveValue.Builder(); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder setType(TypeNode type); + + public abstract Builder setValue(String value); + + abstract PrimitiveValue autoBuild(); + + public PrimitiveValue build() throws TypeMismatchException { + // TODO(unsupported): byte, short, char, array initialization. + // TODO(miraleung): Object type checking? + PrimitiveValue primitiveValue = autoBuild(); + TypeNode type = primitiveValue.type(); + String value = primitiveValue.value(); + if (!typeMatchesValue(type, value)) { + throw new TypeMismatchException( + String.format("Type %s does not match value %s", type.typeKind(), value)); + } + return primitiveValue; + } + + private static boolean typeMatchesValue(TypeNode type, String value) { + switch (type.typeKind()) { + case INT: + return Literal.isIntegerLiteral(value); + case LONG: + return Literal.isLongLiteral(value); + case FLOAT: + return Literal.isFloatLiteral(value); + case DOUBLE: + return Literal.isDoubleLiteral(value); + case BOOLEAN: + return Literal.isBooleanLiteral(value); + case OBJECT: // Fall through. + case BYTE: // Fall through. + case CHAR: // Fall through. + case SHORT: // Fall through. + default: + } + return false; + } + } +} diff --git a/src/main/java/com/google/api/generator/engine/ast/Value.java b/src/main/java/com/google/api/generator/engine/ast/Value.java new file mode 100644 index 0000000000..e831c74713 --- /dev/null +++ b/src/main/java/com/google/api/generator/engine/ast/Value.java @@ -0,0 +1,17 @@ +// Copyright 2020 Google LLC +// +// 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. + +package com.google.api.generator.engine.ast; + +public interface Value {} diff --git a/src/test/java/com/google/api/generator/engine/ast/BUILD.bazel b/src/test/java/com/google/api/generator/engine/ast/BUILD.bazel index 28ea7ebdba..08251210a4 100644 --- a/src/test/java/com/google/api/generator/engine/ast/BUILD.bazel +++ b/src/test/java/com/google/api/generator/engine/ast/BUILD.bazel @@ -2,6 +2,7 @@ package(default_visibility = ["//visibility:public"]) TESTS = [ "IdentifierNodeTest", + "PrimitiveValueTest", ] filegroup( diff --git a/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java new file mode 100644 index 0000000000..6d7428eab4 --- /dev/null +++ b/src/test/java/com/google/api/generator/engine/ast/PrimitiveValueTest.java @@ -0,0 +1,64 @@ +// Copyright 2020 Google LLC +// +// 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. + +package com.google.api.generator.engine.ast; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.generator.engine.ast.PrimitiveValue.TypeMismatchException; +import com.google.api.generator.engine.ast.TypeNode.TypeKind; +import org.junit.Test; + +public class PrimitiveValueTest { + @Test + public void createPrimitiveValue_basic() { + assertValidValue(TypeKind.INT, "3"); + assertValidValue(TypeKind.BOOLEAN, "false"); + assertValidValue(TypeKind.LONG, "123"); + assertValidValue(TypeKind.FLOAT, "123.f"); + assertValidValue(TypeKind.DOUBLE, "123e10"); + } + + @Test + public void createPrimitiveValue_invalid() { + assertInvalidValue(TypeKind.INT, "123.f"); + assertInvalidValue(TypeKind.INT, "false"); + assertInvalidValue(TypeKind.BOOLEAN, "False"); + assertInvalidValue(TypeKind.FLOAT, "asdfg"); + } + + @Test + public void createPrimitiveValue_unsupported() { + assertInvalidValue(TypeKind.BYTE, "0x2"); + assertInvalidValue(TypeKind.SHORT, "1"); + assertInvalidValue(TypeKind.CHAR, "a"); + } + + private static void assertValidValue(TypeKind typeKind, String value) { + TypeNode type = TypeNode.builder().setTypeKind(typeKind).build(); + PrimitiveValue primitiveValue = PrimitiveValue.builder().setType(type).setValue(value).build(); + assertThat(primitiveValue.value()).isEqualTo(value); + assertThat(primitiveValue.type()).isEqualTo(type); + } + + private void assertInvalidValue(TypeKind typeKind, String value) { + TypeNode type = TypeNode.builder().setTypeKind(typeKind).build(); + assertThrows( + TypeMismatchException.class, + () -> { + PrimitiveValue.builder().setType(type).setValue(value).build(); + }); + } +}