use of com.linkedin.avroutil1.model.AvroName in project avro-util by linkedin.
the class AvscWriter method toJson.
protected void toJson(Schema schema, AvroNames names, String contextNamespaceWhenParsed, String contextNamespaceWhenParsedUnder702, G gen) throws IOException {
Avro702Data avro702Data;
switch(schema.getType()) {
case ENUM:
// taken from EnumSchema.toJson() in avro 1.11
if (writeNameRef(schema, names, gen)) {
return;
}
gen.writeStartObject();
gen.writeStringField("type", "enum");
avro702Data = writeName(schema, names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
if (schema.getDoc() != null) {
gen.writeStringField("doc", schema.getDoc());
}
gen.writeArrayFieldStart("symbols");
for (String symbol : schema.getEnumSymbols()) {
gen.writeString(symbol);
}
gen.writeEndArray();
writeEnumDefault(schema, gen);
writeProps(schema, gen);
aliasesToJson(schema, avro702Data.getExtraAliases(), gen);
gen.writeEndObject();
break;
case FIXED:
// taken from FixedSchema.toJson() in avro 1.11
if (writeNameRef(schema, names, gen)) {
return;
}
gen.writeStartObject();
gen.writeStringField("type", "fixed");
avro702Data = writeName(schema, names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
if (schema.getDoc() != null) {
gen.writeStringField("doc", schema.getDoc());
}
gen.writeNumberField("size", schema.getFixedSize());
writeProps(schema, gen);
aliasesToJson(schema, avro702Data.getExtraAliases(), gen);
gen.writeEndObject();
break;
case RECORD:
// taken from RecordSchema.toJson() in avro 1.11
if (writeNameRef(schema, names, gen)) {
return;
}
gen.writeStartObject();
gen.writeStringField("type", schema.isError() ? "error" : "record");
avro702Data = writeName(schema, names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
AvroName name = AvroName.of(schema);
// save current namespaces - both 1.4 and correct one
// save avro-702 mode namespace
String savedBadSpace = names.badSpace();
// save correct namespace
String savedCorrectSpace = names.correctSpace();
// avro 1.4 only ever sets namespace if the current is null
if (savedBadSpace == null) {
names.badSpace(name.getSpace());
}
// always update correct namespace
names.correctSpace(name.getSpace());
if (schema.getDoc() != null) {
gen.writeStringField("doc", schema.getDoc());
}
if (schema.getFields() != null) {
gen.writeFieldName("fields");
fieldsToJson(schema, names, avro702Data.getNamespaceWhenParsing(), avro702Data.getNamespaceWhenParsing702(), gen);
}
writeProps(schema, gen);
aliasesToJson(schema, avro702Data.getExtraAliases(), gen);
gen.writeEndObject();
// avro 1.4 never restores namespace, so we never restore space
// always restore correct namespace
names.correctSpace(savedCorrectSpace);
break;
case ARRAY:
// taken from ArraySchema.toJson() in avro 1.11
gen.writeStartObject();
gen.writeStringField("type", "array");
gen.writeFieldName("items");
toJson(schema.getElementType(), names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
writeProps(schema, gen);
gen.writeEndObject();
break;
case MAP:
// taken from MapSchema.toJson() in avro 1.11
gen.writeStartObject();
gen.writeStringField("type", "map");
gen.writeFieldName("values");
toJson(schema.getValueType(), names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
writeProps(schema, gen);
gen.writeEndObject();
break;
case UNION:
// taken from UnionSchema.toJson() in avro 1.11
gen.writeStartArray();
for (Schema type : schema.getTypes()) {
toJson(type, names, contextNamespaceWhenParsed, contextNamespaceWhenParsedUnder702, gen);
}
gen.writeEndArray();
break;
default:
// all other schema types (taken from Schema.toJson() in avro 1.11)
if (!hasProps(schema)) {
// no props defined
// just write name
gen.writeString(schema.getName());
} else {
gen.writeStartObject();
gen.writeStringField("type", schema.getName());
writeProps(schema, gen);
gen.writeEndObject();
}
}
}
use of com.linkedin.avroutil1.model.AvroName in project avro-util by linkedin.
the class AvscWriter method writeNameRef.
// returns true if this schema (by fullname) is in names, hence has been written before, and so now
// just a "ref" (fullname string) will do
protected boolean writeNameRef(Schema schema, AvroNames names, G gen) throws IOException {
AvroName name = AvroName.of(schema);
if (schema.equals(names.get(name))) {
// "context" namespace depends on which "mode" we're generating in.
String contextNamespace = preAvro702 ? names.badSpace() : names.correctSpace();
gen.writeString(name.getQualified(contextNamespace));
return true;
}
if (!name.isAnonymous()) {
// mark as "seen"
names.put(name, schema);
}
return false;
}
use of com.linkedin.avroutil1.model.AvroName in project avro-util by linkedin.
the class AvscSchemaWriter method writeNamedSchema.
protected JsonValue writeNamedSchema(AvroNamedSchema schema, AvscWriterContext context, AvscWriterConfig config) {
boolean seenBefore = context.schemaEncountered(schema);
if (seenBefore) {
return writeSchemaRef(schema, context, config);
}
// common parts to all named schemas
JsonObjectBuilder definitionBuilder = Json.createObjectBuilder();
AvroName extraAlias = emitSchemaName(schema, context, config, definitionBuilder);
emitSchemaAliases(schema, context, config, extraAlias, definitionBuilder);
if (schema.getDoc() != null) {
definitionBuilder.add("doc", Json.createValue(schema.getDoc()));
}
AvroType type = schema.type();
switch(type) {
case ENUM:
AvroEnumSchema enumSchema = (AvroEnumSchema) schema;
definitionBuilder.add("type", "enum");
List<String> symbols = enumSchema.getSymbols();
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
for (String symbol : symbols) {
arrayBuilder.add(symbol);
}
definitionBuilder.add("symbols", arrayBuilder);
String defaultSymbol = enumSchema.getDefaultSymbol();
if (defaultSymbol != null) {
definitionBuilder.add("default", Json.createValue(defaultSymbol));
}
break;
case FIXED:
AvroFixedSchema fixedSchema = (AvroFixedSchema) schema;
definitionBuilder.add("type", "fixed");
definitionBuilder.add("size", Json.createValue(fixedSchema.getSize()));
break;
case RECORD:
AvroRecordSchema recordSchema = (AvroRecordSchema) schema;
// TODO - support error types?
definitionBuilder.add("type", "record");
emitRecordFields(recordSchema, context, config, definitionBuilder);
break;
default:
throw new IllegalStateException("not expecting " + type);
}
emitJsonProperties(schema, context, config, definitionBuilder);
context.popNamingContext();
return definitionBuilder.build();
}
use of com.linkedin.avroutil1.model.AvroName in project avro-util by linkedin.
the class AvscSchemaWriter method emitSchemaName.
protected AvroName emitSchemaName(AvroNamedSchema schema, AvscWriterContext context, AvscWriterConfig config, JsonObjectBuilder output) {
// before we get to actually writing anything we need to do some accounting of what horrible old avro would do for 702
AvroName schemaName = schema.getName();
// what would ancient avro do?
String contextNamespaceAfter702;
boolean shouldEmitNSPre702 = shouldEmitNamespace(schemaName, context.getAvro702ContextNamespace());
if (shouldEmitNSPre702) {
contextNamespaceAfter702 = schema.getNamespace();
} else {
contextNamespaceAfter702 = context.getAvro702ContextNamespace();
}
// what would modern avro do?
String contextNamespaceAfter;
boolean shouldEmitNSNormally = shouldEmitNamespace(schemaName, context.getCorrectContextNamespace());
if (shouldEmitNSNormally) {
contextNamespaceAfter = schema.getNamespace();
} else {
contextNamespaceAfter = context.getCorrectContextNamespace();
}
// how will Schema.parse() read the output of ancient and modern avro?
AvroName fullnameWhenParsedUnder702 = new AvroName(schemaName.getSimpleName(), contextNamespaceAfter702);
AvroName fullnameWhenParsed = new AvroName(schemaName.getSimpleName(), contextNamespaceAfter);
AvroName extraAlias = null;
if (!fullnameWhenParsed.equals(fullnameWhenParsedUnder702)) {
if (config.isUsePreAvro702Logic()) {
extraAlias = fullnameWhenParsed;
} else {
extraAlias = fullnameWhenParsedUnder702;
}
}
if (config.isAlwaysEmitNamespace()) {
if (config.isEmitNamespacesSeparately() || schemaName.getNamespace().isEmpty()) {
// there's no way to build a fullname for something in the empty namespace
// so for those we always need to emit an empty namespace prop.
output.add("namespace", schemaName.getNamespace());
output.add("name", schemaName.getSimpleName());
} else {
output.add("name", schemaName.getFullname());
}
} else {
boolean emitNS = config.isUsePreAvro702Logic() ? shouldEmitNSPre702 : shouldEmitNSNormally;
if (emitNS) {
output.add("namespace", schemaName.getNamespace());
}
output.add("name", schemaName.getSimpleName());
}
context.pushNamingContext(schema, contextNamespaceAfter, contextNamespaceAfter702);
return extraAlias;
}
use of com.linkedin.avroutil1.model.AvroName in project avro-util by linkedin.
the class AvscParser method parseAliases.
private List<AvroName> parseAliases(JsonObjectExt objectNode, AvscFileParseContext context, AvroType avroType, AvroName name) {
JsonArrayExt aliasesArray = getOptionalArray(objectNode, "aliases");
if (aliasesArray == null || aliasesArray.isEmpty()) {
return null;
}
List<AvroName> aliases = new ArrayList<>(aliasesArray.size());
for (int i = 0; i < aliasesArray.size(); i++) {
// !=null
JsonValueExt aliasNode = (JsonValueExt) aliasesArray.get(i);
JsonValue.ValueType fieldNodeType = aliasNode.getValueType();
if (fieldNodeType != JsonValue.ValueType.STRING) {
throw new AvroSyntaxException("alias " + i + " for " + name.getSimpleName() + " at " + aliasNode.getStartLocation() + " expected to be a STRING, not a " + JsonPUtil.describe(fieldNodeType) + " (" + aliasNode + ")");
}
String aliasStr = ((JsonStringExt) aliasNode).getString();
AvroName alias;
if (aliasStr.contains(".")) {
int lastDot = aliasStr.lastIndexOf('.');
alias = new AvroName(aliasStr.substring(lastDot + 1), aliasStr.substring(0, lastDot));
} else {
alias = new AvroName(aliasStr, name.getNamespace());
}
if (aliases.contains(alias)) {
TextLocation fieldStartLocation = Util.convertLocation(aliasNode.getStartLocation());
TextLocation fieldEndLocation = Util.convertLocation(aliasNode.getEndLocation());
CodeLocation aliasCodeLocation = new CodeLocation(context.getUri(), fieldStartLocation, fieldEndLocation);
context.addIssue(AvscIssues.duplicateAlias(alias.getFullname(), aliasCodeLocation));
} else {
aliases.add(alias);
}
}
return aliases;
}
Aggregations